3 Part of the swftools package.
5 Copyright (c) 2006 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 */
29 #include "../gfxdevice.h"
30 #include "../gfxtools.h"
33 typedef struct _textpage {
37 struct _textpage*next;
40 typedef struct _internal {
41 textpage_t*first_page;
42 textpage_t*current_page;
48 int text_setparameter(gfxdevice_t*dev, const char*key, const char*value)
50 internal_t*i = (internal_t*)dev->internal;
53 void text_startpage(gfxdevice_t*dev, int width, int height)
55 internal_t*i = (internal_t*)dev->internal;
57 i->first_page = i->current_page = (textpage_t*)malloc(sizeof(textpage_t));
59 i->current_page->next = (textpage_t*)malloc(sizeof(textpage_t));
60 i->current_page = i->current_page->next;
62 i->current_page->textsize = 4096;
63 i->current_page->text = (char*)malloc(i->current_page->textsize);
64 i->current_page->textpos = 0;
65 i->current_page->next = 0;
70 void text_startclip(gfxdevice_t*dev, gfxline_t*line)
72 internal_t*i = (internal_t*)dev->internal;
74 void text_endclip(gfxdevice_t*dev)
76 internal_t*i = (internal_t*)dev->internal;
78 void text_stroke(gfxdevice_t*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit)
80 internal_t*i = (internal_t*)dev->internal;
82 void text_fill(gfxdevice_t*dev, gfxline_t*line, gfxcolor_t*color)
84 internal_t*i = (internal_t*)dev->internal;
86 void text_fillbitmap(gfxdevice_t*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform)
88 internal_t*i = (internal_t*)dev->internal;
90 void text_fillgradient(gfxdevice_t*dev, gfxline_t*line, gfxgradient_t*gradient, gfxgradienttype_t type, gfxmatrix_t*matrix)
92 internal_t*i = (internal_t*)dev->internal;
94 void text_addfont(gfxdevice_t*dev, gfxfont_t*font) {}
96 static void addchar(gfxdevice_t*dev, int unicode)
98 internal_t*i = (internal_t*)dev->internal;
99 if(!i->current_page) {
100 text_startpage(dev, 0, 0);
102 if(i->current_page->textpos + 10 > i->current_page->textsize) {
103 i->current_page->textsize += 4096;
104 i->current_page->text = realloc(i->current_page->text, i->current_page->textsize);
106 writeUTF8(unicode, &i->current_page->text[i->current_page->textpos]);
107 i->current_page->textpos += strlen(&i->current_page->text[i->current_page->textpos]);
110 void text_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color, gfxmatrix_t*matrix)
112 internal_t*i = (internal_t*)dev->internal;
113 double xshift = matrix->tx - i->currentx;
114 double yshift = matrix->ty - i->currenty;
115 i->currentx = matrix->tx;
116 i->currenty = matrix->ty;
118 if(fabs(yshift)>1.0) {
120 } else if(xshift > i->lastadvance*1.3 || xshift<0) {
125 i->lastadvance = font->glyphs[glyphnr].advance*matrix->m00;
126 u = font->glyphs[glyphnr].unicode;
129 i->currentx = 0;i->currenty = 0;
136 void text_drawlink(gfxdevice_t*dev, gfxline_t*line, const char*action)
138 internal_t*i = (internal_t*)dev->internal;
141 void text_endpage(gfxdevice_t*dev)
143 internal_t*i = (internal_t*)dev->internal;
146 void text_result_write(gfxresult_t*r, int filedesc)
148 textpage_t*i= (textpage_t*)r->internal;
150 int text_result_save(gfxresult_t*r, char*filename)
152 textpage_t*i= (textpage_t*)r->internal;
154 return 0; // no pages drawn
156 FILE*fi = fopen(filename, "wb");
160 fwrite(i->text, i->textpos, 1, fi);
166 void*text_result_get(gfxresult_t*r, char*name)
168 textpage_t*i= (textpage_t*)r->internal;
169 if(!strcmp(name,"text")) {
176 char*text = (char*)malloc(len);
180 memcpy(&text[pos], i->text, i->textpos);
186 } else if(!strncmp(name,"page",4)) {
187 int pagenr = atoi(&name[4]);
195 i->text[i->textpos] = 0;
196 return strdup(i->text);
200 void text_result_destroy(gfxresult_t*r)
202 textpage_t*i= (textpage_t*)r->internal;
205 textpage_t*next = i->next;
206 free(i->text);i->text = 0;
213 gfxresult_t* text_finish(struct _gfxdevice*dev)
215 internal_t*i = (internal_t*)dev->internal;
217 gfxresult_t* res = (gfxresult_t*)rfx_calloc(sizeof(gfxresult_t));
219 res->internal = i->first_page;i->first_page = 0;i->current_page=0;
220 res->write = text_result_write;
221 res->save = text_result_save;
222 res->get = text_result_get;
223 res->destroy = text_result_destroy;
225 free(dev->internal); dev->internal = 0; i = 0;
232 void gfxdevice_text_init(gfxdevice_t*dev, gfxdevice_t*out)
234 internal_t*i = (internal_t*)rfx_calloc(sizeof(internal_t));
235 memset(dev, 0, sizeof(gfxdevice_t));
241 dev->setparameter = text_setparameter;
242 dev->startpage = text_startpage;
243 dev->startclip = text_startclip;
244 dev->endclip = text_endclip;
245 dev->stroke = text_stroke;
246 dev->fill = text_fill;
247 dev->fillbitmap = text_fillbitmap;
248 dev->fillgradient = text_fillgradient;
249 dev->addfont = text_addfont;
250 dev->drawchar = text_drawchar;
251 dev->drawlink = text_drawlink;
252 dev->endpage = text_endpage;
253 dev->finish = text_finish;