/*
* Inkscape::Text::Layout::ScanlineMaker - text layout engine shape measurers
*
* Authors:
* Richard Hughes <cyreve@users.sf.net>
*
* Copyright (C) 2005 Richard Hughes
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "Layout-TNG-Scanline-Maker.h"
#include "livarot/float-line.h"
#include <limits>
namespace Inkscape {
namespace Text {
// *********************** infinite version
Layout::InfiniteScanlineMaker::InfiniteScanlineMaker(double initial_x, double initial_y, Layout::Direction block_progression)
{
switch (block_progression) {
case LEFT_TO_RIGHT:
case RIGHT_TO_LEFT:
break;
default:
break;
}
_negative_block_progression = block_progression == RIGHT_TO_LEFT || block_progression == BOTTOM_TO_TOP;
}
{
}
std::vector<Layout::ScanlineMaker::ScanRun> Layout::InfiniteScanlineMaker::makeScanline(Layout::FontMetrics const &line_height)
{
runs[0].x_end = std::numeric_limits<float>::max(); // we could use DBL_MAX, but this just seems safer
return runs;
}
{
else
}
{
}
bool Layout::InfiniteScanlineMaker::canExtendCurrentScanline(Layout::FontMetrics const &line_height)
{
return true;
}
{
}
// *********************** real shapes version
Layout::ShapeScanlineMaker::ShapeScanlineMaker(Shape const *shape, Layout::Direction block_progression)
{
if (block_progression == TOP_TO_BOTTOM) {
_shape_needs_freeing = false;
} else {
_shape_needs_freeing = true;
switch (block_progression) {
case BOTTOM_TO_TOP: temp_rotated_shape->Transform(Geom::Affine(1.0, 0.0, 0.0, -1.0, 0.0, 0.0)); break; // reflect about x axis
case LEFT_TO_RIGHT: temp_rotated_shape->Transform(Geom::Affine(0.0, 1.0, 1.0, 0.0, 0.0, 0.0)); break; // reflect about y=x
case RIGHT_TO_LEFT: temp_rotated_shape->Transform(Geom::Affine(0.0, -1.0, 1.0, 0.0, 0.0, 0.0)); break; // reflect about y=-x
default: break;
}
_rotated_shape = new Shape;
delete temp_rotated_shape;
}
_rotated_shape->CalcBBox(true);
_negative_block_progression = block_progression == RIGHT_TO_LEFT || block_progression == BOTTOM_TO_TOP;
}
{
if (_shape_needs_freeing)
delete _rotated_shape;
}
std::vector<Layout::ScanlineMaker::ScanRun> Layout::ShapeScanlineMaker::makeScanline(Layout::FontMetrics const &line_height)
{
if (_y > _bounding_box_bottom)
if (_y < _bounding_box_top)
if (line_text_height == 0.0)
// I think what's going on here is that we're moving the top of the scanline to the given position...
// ...then actually retreiving the scanline (which alters the first two parameters)
_rotated_shape->Scan(_rasterizer_y, _current_rasterization_point, _y + line_text_height , &line_rasterization, true, line_text_height);
// sanitise the raw rasterisation, which could have weird overlaps
// line_rasterization.Affiche();
// cut out runs that cover less than 90% of the line
{
// make up a pointless run: anything that's not an empty vector
return result;
}
// convert the FloatLigne to what we use: vector<ScanRun>
}
return result;
}
{
}
{
if (_negative_block_progression) return - _y;
return _y;
}
{
// what will happen with the rasteriser if we move off the shape?
// it's not an important question because <flowSpan> doesn't have a y attribute
}
bool Layout::ShapeScanlineMaker::canExtendCurrentScanline(Layout::FontMetrics const &/*line_height*/)
{
//we actually could return true if only the leading changed, but that's too much effort for something that rarely happens
return false;
}
{
}
}//namespace Text
}//namespace Inkscape