summaryrefslogtreecommitdiff
path: root/dviware/dvi2bitmap/Bitmap.h
blob: b43203ade52114c4fb8944a72deafe5b4b1a66e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/* This file is part of dvi2bitmap; see README for copyrights and licence */


#ifndef BITMAP_HEADER_READ
#define BITMAP_HEADER_READ 1

#include "Byte.h"
//#include "DviFile.h"            /* needed by BitmapMark */
#include "DviFilePosition.h"
#include "DviError.h"
#include "verbosity.h"

class BitmapError : public DviError {
 public:
    BitmapError(string s) : DviError(s) { };
};

/**
 * Represents an abstract bitmap.
 * The bitmaps written to file are subclasses of the class {@link BitmapImage}.
 */
class Bitmap {
 public:
    Bitmap (const int width, const int height, const int bpp=1,
	    bool expandable=true,
	    const int maxwidth=-1, const int maxheight=-1)
	    throw (BitmapError);
    ~Bitmap();

    // make sure Left..Bottom are 0..3 (I should use an iterator, I know...)
    enum Margin { Left=0, Right=1, Top=2, Bottom=3, All};

    void paint (const int x, const int y, const int w, const int h,
		const Byte* b)
	    throw (BitmapError);
    void rule (const int x, const int y, const int w, const int h)
	    throw (BitmapError);
    void strut (const int x, const int y,
		const int l, const int r,
		const int t, const int b)
	    throw (BitmapError);
    void write (const string filename, const string format)
	    throw (BitmapError);
    void freeze ();
    void crop ();
    static void cropDefault (Margin spec, int pixels, bool absolute=false)
	    throw (BitmapError);
    void crop (Margin spec, int pixels, bool absolute=false)
	    throw (BitmapError);
    void blur ();
    void clear();
    /**
     * Sets the current bitmap to be transparent, if possible.
     * @param sw if true, the current bitmap is set to be transparent
     */
    void setTransparent(const bool sw) { transparent_ = sw; }
    typedef struct BitmapColour_s {
	Byte red, green, blue;
    } BitmapColour;
    void setRGB (const bool fg, const BitmapColour*);
    static void setDefaultRGB (const bool fg, const BitmapColour*);
    void scaleDown (const int factor)
	    throw (BitmapError);
    /**
     * Is the bitmap empty?  If nothing has (yet) been written to the
     * bitmap, or if everything that was written was out of
     * bounds, then the bitmap is empty.
     *
     * @return true if the bitmap is empty
     */
    bool empty () const
	{ return (bbL > W || bbR < 0 || bbT > H || bbB < 0); }
    bool overlaps() const;
    int* boundingBox();
    /**
     * Returns the total width of the bitmap.  This may not the the
     * initial size of the bitmap, if it has expanded since then.
     * @return width of bitmap
     */
    int getWidth() const { return W; }
    /**
     * Returns the total height of the bitmap.  This may not the the
     * initial size of the bitmap, if it has expanded since then.
     * @return height of bitmap
     */
    int getHeight() const { return H; }
    /**
     * Sets the verbosity of the current class.
     * @param level the required verbosity
     * @return the previous verbosity level
     */
    static verbosities verbosity (const verbosities level) {
	enum verbosities oldv = verbosity_;
	verbosity_ = level;
	return oldv;
    }
    /**
     * Sets whether bitmap information is logged.  If logging is
     * enabled, then the details of the bitmaps are sent to the
     * <code>stdout</code> prefixed by the given string.
     *
     * @param prefix if non-null, then bitmap activity is logged on
     * stdout with this prefix; if null, such logging is turned off
     */
    static void logBitmapInfo (const char *prefix) {
        logBitmapPrefix_ = prefix;
    };

#if 0
    /**
     * Represents a location within the bitmap.  Coordinates
     * <code>x</code> and <code>y</code> are relative to the top-left
     * corner of the bitmap, with the pixel in the top-left corner
     * having coordinates (0,0).
     *
     * <p>See {@link #mark} and {@link #getMark}.
     */
    class BitmapMark {
    private:
        double x, y;
        DviFile* dvif;
    public:
        BitmapMark(DviFile*, double x_sp, double y_sp);
        double getX(const DviFile::DviUnits u);
        double getY(const DviFile::DviUnits u);
        void shift(double dx, double dy, DviFile::DviUnits u);
        void scale(double factor);
        // make a static copy
        BitmapMark* copy();
    };
    void mark(DviFile*, const double x, const double y);
    BitmapMark* getMark();
#endif
    void mark(DviFilePosition*);
    DviFilePosition* getMark();

    /** Iterator class */
    class const_iterator 
    {
    public:
	Byte* operator*() throw (DviError);
	const_iterator& operator++() throw (DviError);
	bool operator==(const const_iterator& it) const;
	bool operator!=(const const_iterator& it) const;
	~const_iterator();
    private:
	const_iterator();
	void init(Byte* b, int startx, int starty, int width, int nrows);
	Byte* b_;
	int rowLength_;
	int rowNumber_;
	int startColumn_;
	int lastRow_;
	friend class Bitmap;
    };
    const_iterator runningIterator_;
    static const_iterator endIterator_;
    const_iterator begin();
    const_iterator end() const;

 private:
    void normalizeBB_(int& l, int& r, int& t, int& b);
    void usesBitmapArea_(const int ulx, const int uly,
			 const int lrx, const int lry);
    /** pointer to bitmap.  Pixel (x,y) is at B[y*W + x]; */
    Byte *B;
    /** width and height of bitmap */
    int W, H;
    /** Maximum height and width */
    int maxW_, maxH_;
    /** is the bitmap to be expandable? */
    bool isExpandable_;
    /** bounding box.  bbL and bbT are the leftmost and topmost
     * blackened pixels, bbR and bbB are one more than the rightmost
     * and lowest blackened pixels.  Until a call to freeze(), bb? may
     * go outside the canvas (ie, may be negative or greater than W or
     * H); afterwards they are bounded by 0..W and 0..H.  These
     * remain the edges of the blackened pixels even after cropping,
     * and so it is the responsibiligy of the boundingBox() method to
     * take cropping into account.
     */
    int bbL, bbR, bbT, bbB;
    /** holds return values for boundingBox() */
    int BB[4];
    /** Flag is set true when the bitmap is frozen */
    bool frozen_;
    /** cropX is the value of bbX when the crop() method was called */
    int cropL, cropR, cropT, cropB;
    /** Flag is set true when the bitmap is frozen */
    bool cropped_;
    /** Flag is set true when the bitmap is scaled */
    bool scaled_;
    /** Location of mark */
    DviFilePosition* mark_;
    /** When cropping, set margins.  Indexed by enumerator Bitmap::Margin. */
    static int  cropMarginDefault[4];
    int  cropMargin[4];
    static bool cropMarginAbsDefault[4];
    bool cropMarginAbs[4];
    /** If true, make background transparent if possible */
    bool transparent_;
    BitmapColour fg_, bg_;
    /** If true, custom colours have been set */
    bool customRGB_;
    /** Default background colours */
    static BitmapColour def_fg_, def_bg_;
    static bool def_customRGB_;
    /** bits-per-pixel */
    int bpp_;
    /** Maximum colour index (must fit into a Byte) */
    Byte max_colour_;
    /** The reporting verbosity level */
    static verbosities verbosity_;
    /** The prefix when reporting bitmap information.  Set to zero to suppress */
    static const char* logBitmapPrefix_;
};

#endif //#ifndef BITMAP_HEADER_READ