1 /* remove_invisible_characters.c
3 Part of the swftools package.
5 Copyright (c) 2011 Matthias Kramm <kramm@quiss.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
24 #include "../gfxfilter.h"
25 #include "../gfxtools.h"
26 #include "../gfxfont.h"
27 #include "../gfxpoly.h"
28 #include "../gfximage.h"
31 #include "../devices/render.h"
33 typedef struct _page
{
40 typedef struct _internal
{
52 static gfxcolor_t black
= {255,0,0,0};
54 static void pass1_startpage(gfxfilter_t
*f
, int width
, int height
, gfxdevice_t
*out
)
56 internal_t
*i
= (internal_t
*)f
->internal
;
57 gfxdevice_render_init(&i
->render
);
58 i
->render
.startpage(&i
->render
, width
, height
);
59 out
->startpage(out
, width
, height
);
62 static void pass1_endpage(gfxfilter_t
*f
, gfxdevice_t
*out
)
64 internal_t
*i
= (internal_t
*)f
->internal
;
65 i
->render
.endpage(&i
->render
);
67 gfxresult_t
*result
= i
->render
.finish(&i
->render
);
69 page_t
*page
= (page_t
*)rfx_calloc(sizeof(page_t
));
71 i
->first_page
= i
->last_page
= i
->current_page
= page
;
73 i
->last_page
->next
= page
;
76 page
->size
= i
->count
+ 1;
77 page
->size8
= (page
->size
+7) >> 3;
78 page
->visible
= (uint8_t*)rfx_calloc(page
->size8
);
80 gfximage_t
*img
= (gfximage_t
*)result
->get(result
, "page0");
81 int size
= img
->width
*img
->height
;
84 int index
= ((*(uint32_t*)&img
->data
[t
])>>8);
85 page
->visible
[index
>>3] |= (1<<(index
&7));
87 result
->destroy(result
);
89 static void pass1_fill(gfxfilter_t
*f
, gfxline_t
*line
, gfxcolor_t
*color
, gfxdevice_t
*out
)
91 internal_t
*i
= (internal_t
*)f
->internal
;
93 i
->render
.fill(&i
->render
, line
, &black
);
95 out
->fill(out
, line
, color
);
97 static void pass1_stroke(gfxfilter_t
*f
, gfxline_t
*line
, gfxcoord_t width
, gfxcolor_t
*color
, gfx_capType cap_style
, gfx_joinType joint_style
, gfxcoord_t miterLimit
, gfxdevice_t
*out
)
99 internal_t
*i
= (internal_t
*)f
->internal
;
100 if(color
->a
== 255) {
101 i
->render
.stroke(&i
->render
, line
, width
, &black
, cap_style
, joint_style
, miterLimit
);
103 out
->stroke(out
, line
, width
, color
, cap_style
, joint_style
, miterLimit
);
105 static void pass1_fillbitmap(gfxfilter_t
*f
, gfxline_t
*line
, gfximage_t
* bitmap
, gfxmatrix_t
*imgcoord2devcoord
, gfxcxform_t
*cxform
, gfxdevice_t
*out
)
107 internal_t
*i
= (internal_t
*)f
->internal
;
108 gfximage_t
*img
= gfximage_new(bitmap
->width
, bitmap
->height
);
109 int size
= img
->width
*img
->height
;
110 memset(img
->data
, 0, size
*sizeof(gfxcolor_t
));
112 for(t
=0;t
<size
;t
++) {
113 img
->data
[t
].a
= bitmap
->data
[t
].a
== 255 ? 255 : 0;
115 i
->render
.fillbitmap(&i
->render
, line
, img
, imgcoord2devcoord
, 0);
117 out
->fillbitmap(out
, line
, bitmap
, imgcoord2devcoord
, cxform
);
119 static void pass1_fillgradient(gfxfilter_t
*f
, gfxline_t
*line
, gfxgradient_t
*gradient
, gfxgradienttype_t type
, gfxmatrix_t
*gradcoord2devcoord
, gfxdevice_t
*out
)
121 internal_t
*i
= (internal_t
*)f
->internal
;
122 i
->render
.fill(&i
->render
, line
, &black
);
123 out
->fillgradient(out
, line
, gradient
, type
, gradcoord2devcoord
);
125 static void pass1_startclip(gfxfilter_t
*f
, gfxline_t
*line
, gfxdevice_t
*out
)
127 internal_t
*i
= (internal_t
*)f
->internal
;
128 i
->render
.startclip(&i
->render
, line
);
129 out
->startclip(out
, line
);
131 static void pass1_endclip(gfxfilter_t
*f
, gfxdevice_t
*out
)
133 internal_t
*i
= (internal_t
*)f
->internal
;
134 i
->render
.endclip(&i
->render
);
137 static void pass1_addfont(gfxfilter_t
*f
, gfxfont_t
*font
, gfxdevice_t
*out
)
139 internal_t
*i
= (internal_t
*)f
->internal
;
140 /* Don't pass this to device->render(). We're not in a page
141 yet, and the render device doesn't need addfont() */
142 //i->render.addfont(&i->render, font);
143 out
->addfont(out
, font
);
145 static void pass1_drawchar(gfxfilter_t
*f
, gfxfont_t
*font
, int glyphnr
, gfxcolor_t
*color
, gfxmatrix_t
*matrix
, gfxdevice_t
*out
)
147 internal_t
*i
= (internal_t
*)f
->internal
;
150 *(uint32_t*)&c
= i
->count
<<8|0xff;
152 double advance
= font
->glyphs
[glyphnr
].advance
;
153 gfxline_t
*box
= gfxline_makerectangle(0,0,advance
,font
->ascent
);
154 gfxline_transform(box
, matrix
);
155 i
->render
.fill(&i
->render
, box
, &c
);
156 if(font
->ascent
< 512) {
157 i
->render
.drawchar(&i
->render
, font
, glyphnr
, &c
, matrix
);
161 out
->drawchar(out
, font
, glyphnr
, color
, matrix
);
163 static gfxresult_t
*pass1_finish(gfxfilter_t
*f
, gfxdevice_t
*out
)
165 internal_t
*i
= (internal_t
*)f
->internal
;
166 return out
->finish(out
);
169 static void pass2_startpage(gfxfilter_t
*f
, int width
, int height
, gfxdevice_t
*out
)
171 internal_t
*i
= (internal_t
*)f
->internal
;
172 out
->startpage(out
, width
, height
);
175 static void pass2_endpage(gfxfilter_t
*f
, gfxdevice_t
*out
)
177 internal_t
*i
= (internal_t
*)f
->internal
;
178 i
->current_page
= i
->current_page
->next
;
181 static void pass2_addfont(gfxfilter_t
*f
, gfxfont_t
*font
, gfxdevice_t
*out
)
183 internal_t
*i
= (internal_t
*)f
->internal
;
184 out
->addfont(out
, font
);
186 static void pass2_drawchar(gfxfilter_t
*f
, gfxfont_t
*font
, int glyphnr
, gfxcolor_t
*color
, gfxmatrix_t
*matrix
, gfxdevice_t
*out
)
188 internal_t
*i
= (internal_t
*)f
->internal
;
190 if(i
->current_page
->visible
[i
->count
>>3]&(1<<(i
->count
&7))) {
191 out
->drawchar(out
, font
, glyphnr
, color
, matrix
);
194 gfxline_t
*line
= gfxline_clone(font
->glyphs
[glyphnr
].line
);
195 gfxline_transform(line
, matrix
);
196 gfxpoly_t
*poly
= gfxpoly_from_fill(line
, 0.05);
197 double area
= gfxpoly_area(poly
);
198 gfxpoly_destroy(poly
);
204 static gfxresult_t
*pass2_finish(gfxfilter_t
*f
, gfxdevice_t
*out
)
206 internal_t
*i
= (internal_t
*)f
->internal
;
208 printf("%f\n", i
->area
);
210 return out
->finish(out
);
213 void gfxtwopassfilter_remove_invisible_characters_init(gfxtwopassfilter_t
*f
)
215 internal_t
*i
= (internal_t
*)rfx_calloc(sizeof(internal_t
));
217 memset(f
, 0, sizeof(gfxtwopassfilter_t
));
218 f
->type
= gfxfilter_twopass
;
220 f
->pass1
.name
= "filter \"remove invisible characters\" pass 1";
221 f
->pass1
.addfont
= pass1_addfont
;
222 f
->pass1
.drawchar
= pass1_drawchar
;
223 f
->pass1
.fill
= pass1_fill
;
224 f
->pass1
.fillbitmap
= pass1_fillbitmap
;
225 f
->pass1
.fillgradient
= pass1_fillgradient
;
226 f
->pass1
.stroke
= pass1_stroke
;
227 f
->pass1
.startclip
= pass1_startclip
;
228 f
->pass1
.endclip
= pass1_endclip
;
229 f
->pass1
.startpage
= pass1_startpage
;
230 f
->pass1
.endpage
= pass1_endpage
;
231 f
->pass1
.finish
= pass1_finish
;
232 f
->pass1
.internal
= i
;
234 f
->pass2
.name
= "filter \"remove invisible characters\" pass 2";
235 f
->pass2
.addfont
= pass2_addfont
;
236 f
->pass2
.drawchar
= pass2_drawchar
;
237 f
->pass2
.startpage
= pass2_startpage
;
238 f
->pass2
.endpage
= pass2_endpage
;
239 f
->pass2
.finish
= pass2_finish
;
240 f
->pass2
.internal
= i
;