~valavanisalex/ubuntu/precise/inkscape/fix-943984

« back to all changes in this revision

Viewing changes to inkscape-0.47pre1/src/libnrtype/Layout-TNG-Scanline-Maker.h

  • Committer: Bazaar Package Importer
  • Author(s): Bryce Harrington
  • Date: 2009-07-02 17:09:45 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20090702170945-nn6d6zswovbwju1t
Tags: 0.47~pre1-0ubuntu1
* New upstream release.
  - Don't constrain maximization on small resolution devices (pre0)
    (LP: #348842)
  - Fixes segfault on startup (pre0)
    (LP: #391149)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Inkscape::Text::Layout::ScanlineMaker - text layout engine shape measurers
 
3
 *
 
4
 * Authors:
 
5
 *   Richard Hughes <cyreve@users.sf.net>
 
6
 *
 
7
 * Copyright (C) 2005 Richard Hughes
 
8
 *
 
9
 * Released under GNU GPL, read the file 'COPYING' for more information
 
10
 */
 
11
#ifndef __LAYOUT_TNG_SCANLINE_MAKER_H__
 
12
#define __LAYOUT_TNG_SCANLINE_MAKER_H__
 
13
 
 
14
#include <vector>
 
15
#include <cmath>
 
16
#include "libnrtype/Layout-TNG.h"
 
17
 
 
18
class Shape;
 
19
 
 
20
namespace Inkscape {
 
21
namespace Text {
 
22
 
 
23
/** \brief private to Layout. Generates lists of chunks within a shape.
 
24
 
 
25
This is the abstract base class for taking a given shape and scanning through
 
26
it line-by-line to get the horizontal extents of each chunk for a line of a
 
27
given height. There are two specialisations: One for real shapes and one that
 
28
turns off wrapping by simulating an infinite shape. In due course there will
 
29
be a further specialisation to optimise for the common case where the shape
 
30
is a rectangle.
 
31
*/
 
32
class Layout::ScanlineMaker
 
33
{
 
34
public:
 
35
    virtual ~ScanlineMaker() {}
 
36
 
 
37
    struct ScanRun {
 
38
        double y;  /// that's the top of the scan run, not the baseline
 
39
        double x_start;    // these are not flipped according to the text direction
 
40
        double x_end;
 
41
        inline double width() const {return std::abs(x_start - x_end);}
 
42
    };
 
43
 
 
44
    /** Returns a list of chunks on the current line which can fit text with
 
45
    the given properties. It is up to the caller to discard any chunks which
 
46
    are too narrow for its needs. This function may change the y coordinate
 
47
    between calls if the new height too big to fit in the space remaining in
 
48
    this shape. Returns an empty vector if there is no space left in the
 
49
    current shape. */
 
50
    virtual std::vector<ScanRun> makeScanline(Layout::LineHeight const &line_height) =0;
 
51
 
 
52
    /** Indicates that the caller has successfully filled the current line
 
53
    and hence that the next call to makeScanline() should return lines on
 
54
    the next lower line. There is no error return, the next call to
 
55
    makeScanline() will give an error if there is no more space. */
 
56
    virtual void completeLine() =0;
 
57
 
 
58
    /** Returns the y coordinate of the top of the scanline that will be
 
59
    returned by the next call to makeScanline(). */
 
60
    virtual double yCoordinate() = 0;
 
61
    
 
62
    /** Forces an arbitrary change in the stored y coordinate of the object.
 
63
    The next call to makeScanline() will return runs whose top is at
 
64
    the new coordinate. */
 
65
    virtual void setNewYCoordinate(double new_y) =0;
 
66
 
 
67
    /** Tests whether the caller can fit a new line with the given metrics
 
68
    into exactly the space returned by the previous call to makeScanline().
 
69
    This saves the caller from having to discard its wrapping solution and
 
70
    starting at the beginning of the line again when a larger font is seen.
 
71
    The metrics given here are considered to be the ones that are being
 
72
    used now, and hence is the line advance height used by completeLine().
 
73
    */
 
74
    virtual bool canExtendCurrentScanline(Layout::LineHeight const &line_height) =0;
 
75
};
 
76
 
 
77
/** \brief private to Layout. Generates infinite scanlines for when you don't want wrapping
 
78
 
 
79
This is a 'fake' scanline maker which will always return infinite results,
 
80
effectively turning off wrapping. It's a very simple implementation.
 
81
 
 
82
It does have the curious property, however, that the input coordinates are
 
83
'real' x and y, but the outputs are rotated according to the
 
84
\a block_progression.
 
85
*/
 
86
class Layout::InfiniteScanlineMaker : public Layout::ScanlineMaker
 
87
{
 
88
public:
 
89
    InfiniteScanlineMaker(double initial_x, double initial_y, Layout::Direction block_progression);
 
90
    virtual ~InfiniteScanlineMaker();
 
91
 
 
92
    /** Returns a single infinite run at the current location */
 
93
    virtual std::vector<ScanRun> makeScanline(Layout::LineHeight const &line_height);
 
94
 
 
95
    /** Increments the current y by the current line height */
 
96
    virtual void completeLine();
 
97
 
 
98
    virtual double yCoordinate()
 
99
        {return _y;}
 
100
 
 
101
    /** Just changes y */
 
102
    virtual void setNewYCoordinate(double new_y);
 
103
 
 
104
    /** Always true, but has to save the new height */
 
105
    virtual bool canExtendCurrentScanline(Layout::LineHeight const &line_height);
 
106
 
 
107
private:
 
108
    double _x, _y;
 
109
    Layout::LineHeight _current_line_height;
 
110
    bool _negative_block_progression;     /// if true, indicates that completeLine() should decrement rather than increment, ie block-progression is either rl or bt
 
111
};
 
112
 
 
113
/** \brief private to Layout. Generates scanlines inside an arbitrary shape
 
114
 
 
115
This is the 'perfect', and hence slowest, implementation of a
 
116
Layout::ScanlineMaker, which will return exact bounds for any given
 
117
input shape.
 
118
*/
 
119
class Layout::ShapeScanlineMaker : public Layout::ScanlineMaker
 
120
{
 
121
public:
 
122
    ShapeScanlineMaker(Shape const *shape, Layout::Direction block_progression);
 
123
    virtual ~ShapeScanlineMaker();
 
124
 
 
125
    virtual std::vector<ScanRun> makeScanline(Layout::LineHeight const &line_height);
 
126
 
 
127
    virtual void completeLine();
 
128
 
 
129
    virtual double yCoordinate();
 
130
 
 
131
    virtual void setNewYCoordinate(double new_y);
 
132
 
 
133
    /** never true */
 
134
    virtual bool canExtendCurrentScanline(Layout::LineHeight const &line_height);
 
135
private:
 
136
    /** To generate scanlines for top-to-bottom text it is easiest if we
 
137
    simply rotate the given shape by a multiple of 90 degrees. This stores
 
138
    that. If no rotation was needed we can simply store the pointer we were
 
139
    given and set shape_needs_freeing appropriately. */
 
140
    Shape *_rotated_shape;
 
141
 
 
142
    /// see #rotated_shape;
 
143
    bool _shape_needs_freeing;
 
144
 
 
145
    // Shape::BeginRaster() needs floats rather than doubles
 
146
    float _bounding_box_top, _bounding_box_bottom;
 
147
    float _y;
 
148
    float _rasterizer_y;
 
149
    int _current_rasterization_point;
 
150
    float _current_line_height;
 
151
 
 
152
    bool _negative_block_progression;     /// if true, indicates that completeLine() should decrement rather than increment, ie block-progression is either rl or bt
 
153
};
 
154
 
 
155
}//namespace Text
 
156
}//namespace Inkscape
 
157
 
 
158
#endif
 
159
 
 
160
/*
 
161
  Local Variables:
 
162
  mode:c++
 
163
  c-file-style:"stroustrup"
 
164
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
165
  indent-tabs-mode:nil
 
166
  fill-column:99
 
167
  End:
 
168
*/
 
169
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :