Mercurial > mplayer.hg
annotate libass/ass_bitmap.c @ 27409:e2de11109139
If (has outline) blur(outline) else blur(glyph).
If there is an outline, the glyph itself should not be blurred. Keeps
the border between glyph and outline clear (unblurred), which is
probably how it should be.
Patch by Diogo Franco (diogomfranco gmail com).
author | eugeni |
---|---|
date | Thu, 07 Aug 2008 22:20:58 +0000 |
parents | 588ce97b44f2 |
children | 12e936031c36 |
rev | line source |
---|---|
20008
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
1 // -*- c-basic-offset: 8; indent-tabs-mode: t -*- |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
2 // vim:ts=8:sw=8:noet:ai: |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
3 /* |
26723 | 4 * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> |
5 * | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
6 * This file is part of libass. |
26723 | 7 * |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
8 * libass is free software; you can redistribute it and/or modify |
26723 | 9 * it under the terms of the GNU General Public License as published by |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
13 * libass is distributed in the hope that it will be useful, |
26723 | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License along | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
19 * with libass; if not, write to the Free Software Foundation, Inc., |
26723 | 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
21 */ | |
20008
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
22 |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
23 #include <stdlib.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
24 #include <string.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
25 #include <math.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
26 #include <assert.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
27 #include <ft2build.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
28 #include FT_GLYPH_H |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
29 |
21026
d138463e820b
Collect all includes of mplayer headers in libass in a single file (mputils.h).
eugeni
parents:
20874
diff
changeset
|
30 #include "mputils.h" |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
31 #include "ass_bitmap.h" |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
32 |
19848 | 33 struct ass_synth_priv_s { |
34 int tmp_w, tmp_h; | |
35 unsigned short* tmp; | |
36 | |
37 int g_r; | |
38 int g_w; | |
39 | |
40 unsigned *g; | |
41 unsigned *gt2; | |
42 }; | |
43 | |
44 static const unsigned int maxcolor = 255; | |
45 static const unsigned base = 256; | |
46 static const double blur_radius = 1.5; | |
47 | |
48 static int generate_tables(ass_synth_priv_t* priv, double radius) | |
49 { | |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
50 double A = log(1.0/base)/(radius*radius*2); |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
51 int mx, i; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
52 double volume_diff, volume_factor = 0; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
53 unsigned volume; |
19848 | 54 |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
55 priv->g_r = ceil(radius); |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
56 priv->g_w = 2*priv->g_r+1; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
57 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
58 if (priv->g_r) { |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
59 priv->g = malloc(priv->g_w * sizeof(unsigned)); |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
60 priv->gt2 = malloc(256 * priv->g_w * sizeof(unsigned)); |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
61 if (priv->g==NULL || priv->gt2==NULL) { |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
62 return -1; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
63 } |
19848 | 64 } |
65 | |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
66 if (priv->g_r) { |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
67 // gaussian curve with volume = 256 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
68 for (volume_diff=10000000; volume_diff>0.0000001; volume_diff*=0.5){ |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
69 volume_factor+= volume_diff; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
70 volume=0; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
71 for (i = 0; i<priv->g_w; ++i) { |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
72 priv->g[i] = (unsigned)(exp(A * (i-priv->g_r)*(i-priv->g_r)) * volume_factor + .5); |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
73 volume+= priv->g[i]; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
74 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
75 if(volume>256) volume_factor-= volume_diff; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
76 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
77 volume=0; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
78 for (i = 0; i<priv->g_w; ++i) { |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
79 priv->g[i] = (unsigned)(exp(A * (i-priv->g_r)*(i-priv->g_r)) * volume_factor + .5); |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
80 volume+= priv->g[i]; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
81 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
82 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
83 // gauss table: |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
84 for(mx=0;mx<priv->g_w;mx++){ |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
85 for(i=0;i<256;i++){ |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
86 priv->gt2[mx+i*priv->g_w] = i*priv->g[mx]; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
87 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
88 } |
19848 | 89 } |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
90 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
91 return 0; |
19848 | 92 } |
93 | |
94 static void resize_tmp(ass_synth_priv_t* priv, int w, int h) | |
95 { | |
96 if (priv->tmp_w >= w && priv->tmp_h >= h) | |
97 return; | |
98 if (priv->tmp_w == 0) | |
99 priv->tmp_w = 64; | |
100 if (priv->tmp_h == 0) | |
101 priv->tmp_h = 64; | |
102 while (priv->tmp_w < w) priv->tmp_w *= 2; | |
103 while (priv->tmp_h < h) priv->tmp_h *= 2; | |
104 if (priv->tmp) | |
105 free(priv->tmp); | |
106 priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(short)); | |
107 } | |
108 | |
22886 | 109 ass_synth_priv_t* ass_synth_init(void) |
19848 | 110 { |
111 ass_synth_priv_t* priv = calloc(1, sizeof(ass_synth_priv_t)); | |
112 generate_tables(priv, blur_radius); | |
113 return priv; | |
114 } | |
115 | |
116 void ass_synth_done(ass_synth_priv_t* priv) | |
117 { | |
19962 | 118 if (priv->tmp) |
119 free(priv->tmp); | |
120 if (priv->g) | |
121 free(priv->g); | |
122 if (priv->gt2) | |
123 free(priv->gt2); | |
19848 | 124 free(priv); |
125 } | |
126 | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
127 static bitmap_t* alloc_bitmap(int w, int h) |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
128 { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
129 bitmap_t* bm; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
130 bm = calloc(1, sizeof(bitmap_t)); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
131 bm->buffer = malloc(w*h); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
132 bm->w = w; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
133 bm->h = h; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
134 bm->left = bm->top = 0; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
135 return bm; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
136 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
137 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
138 void ass_free_bitmap(bitmap_t* bm) |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
139 { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
140 if (bm) { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
141 if (bm->buffer) free(bm->buffer); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
142 free(bm); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
143 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
144 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
145 |
19965 | 146 static bitmap_t* copy_bitmap(const bitmap_t* src) |
147 { | |
148 bitmap_t* dst = alloc_bitmap(src->w, src->h); | |
149 dst->left = src->left; | |
150 dst->top = src->top; | |
151 memcpy(dst->buffer, src->buffer, src->w * src->h); | |
152 return dst; | |
153 } | |
154 | |
26035
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
155 static int check_glyph_area(FT_Glyph glyph) |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
156 { |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
157 FT_BBox bbox; |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
158 long long dx, dy; |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
159 FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox); |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
160 dx = bbox.xMax - bbox.xMin; |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
161 dy = bbox.yMax - bbox.yMin; |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
162 if (dx * dy > 8000000) { |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
163 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_GlyphBBoxTooLarge, (int)dx, (int)dy); |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
164 return 1; |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
165 } else |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
166 return 0; |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
167 } |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
168 |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
169 static bitmap_t* glyph_to_bitmap_internal(FT_Glyph glyph, int bord) |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
170 { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
171 FT_BitmapGlyph bg; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
172 FT_Bitmap* bit; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
173 bitmap_t* bm; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
174 int w, h; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
175 unsigned char* src; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
176 unsigned char* dst; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
177 int i; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
178 int error; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
179 |
26035
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
180 if (check_glyph_area(glyph)) |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
181 return 0; |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
182 error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 0); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
183 if (error) { |
21066 | 184 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FT_Glyph_To_BitmapError, error); |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
185 return 0; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
186 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
187 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
188 bg = (FT_BitmapGlyph)glyph; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
189 bit = &(bg->bitmap); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
190 if (bit->pixel_mode != FT_PIXEL_MODE_GRAY) { |
21066 | 191 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UnsupportedPixelMode, (int)(bit->pixel_mode)); |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
192 FT_Done_Glyph(glyph); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
193 return 0; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
194 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
195 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
196 w = bit->width; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
197 h = bit->rows; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
198 bm = alloc_bitmap(w + 2*bord, h + 2*bord); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
199 memset(bm->buffer, 0, bm->w * bm->h); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
200 bm->left = bg->left - bord; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
201 bm->top = - bg->top - bord; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
202 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
203 src = bit->buffer; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
204 dst = bm->buffer + bord + bm->w * bord; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
205 for (i = 0; i < h; ++i) { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
206 memcpy(dst, src, w); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
207 src += bit->pitch; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
208 dst += bm->w; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
209 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
210 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
211 return bm; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
212 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
213 |
19966 | 214 /** |
215 * \brief fix outline bitmap and generate shadow bitmap | |
216 * Two things are done here: | |
217 * 1. Glyph bitmap is subtracted from outline bitmap. This way looks much better in some cases. | |
218 * 2. Shadow bitmap is created as a sum of glyph and outline bitmaps. | |
219 */ | |
19965 | 220 static bitmap_t* fix_outline_and_shadow(bitmap_t* bm_g, bitmap_t* bm_o) |
19856 | 221 { |
222 int x, y; | |
19941
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
223 const int l = bm_o->left > bm_g->left ? bm_o->left : bm_g->left; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
224 const int t = bm_o->top > bm_g->top ? bm_o->top : bm_g->top; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
225 const int r = bm_o->left + bm_o->w < bm_g->left + bm_g->w ? bm_o->left + bm_o->w : bm_g->left + bm_g->w; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
226 const int b = bm_o->top + bm_o->h < bm_g->top + bm_g->h ? bm_o->top + bm_o->h : bm_g->top + bm_g->h; |
19965 | 227 |
228 bitmap_t* bm_s = copy_bitmap(bm_o); | |
229 | |
19941
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
230 unsigned char* g = bm_g->buffer + (t - bm_g->top) * bm_g->w + (l - bm_g->left); |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
231 unsigned char* o = bm_o->buffer + (t - bm_o->top) * bm_o->w + (l - bm_o->left); |
19965 | 232 unsigned char* s = bm_s->buffer + (t - bm_s->top) * bm_s->w + (l - bm_s->left); |
19941
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
233 |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
234 for (y = 0; y < b - t; ++y) { |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
235 for (x = 0; x < r - l; ++x) { |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
236 unsigned char c_g, c_o; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
237 c_g = g[x]; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
238 c_o = o[x]; |
20874 | 239 o[x] = (c_o > c_g) ? c_o : 0; |
19965 | 240 s[x] = (c_o < 0xFF - c_g) ? c_o + c_g : 0xFF; |
19941
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
241 } |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
242 g += bm_g->w; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
243 o += bm_o->w; |
19965 | 244 s += bm_s->w; |
19856 | 245 } |
19965 | 246 |
247 assert(bm_s); | |
248 return bm_s; | |
19856 | 249 } |
250 | |
19965 | 251 int glyph_to_bitmap(ass_synth_priv_t* priv, FT_Glyph glyph, FT_Glyph outline_glyph, |
252 bitmap_t** bm_g, bitmap_t** bm_o, bitmap_t** bm_s, int be) | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
253 { |
19956 | 254 const int bord = be ? ceil(blur_radius) : 0; |
19848 | 255 |
19965 | 256 assert(bm_g && bm_o && bm_s); |
257 | |
258 *bm_g = *bm_o = *bm_s = 0; | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
259 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
260 if (glyph) |
19848 | 261 *bm_g = glyph_to_bitmap_internal(glyph, bord); |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
262 if (!*bm_g) |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
263 return 1; |
19965 | 264 |
19873 | 265 if (outline_glyph) { |
19848 | 266 *bm_o = glyph_to_bitmap_internal(outline_glyph, bord); |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
267 if (!*bm_o) { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
268 ass_free_bitmap(*bm_g); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
269 return 1; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
270 } |
19965 | 271 } |
19873 | 272 if (*bm_o) |
19848 | 273 resize_tmp(priv, (*bm_o)->w, (*bm_o)->h); |
274 resize_tmp(priv, (*bm_g)->w, (*bm_g)->h); | |
275 | |
276 if (be) { | |
19873 | 277 if (*bm_o) |
19848 | 278 blur((*bm_o)->buffer, priv->tmp, (*bm_o)->w, (*bm_o)->h, (*bm_o)->w, (int*)priv->gt2, priv->g_r, priv->g_w); |
27409 | 279 else |
280 blur((*bm_g)->buffer, priv->tmp, (*bm_g)->w, (*bm_g)->h, (*bm_g)->w, (int*)priv->gt2, priv->g_r, priv->g_w); | |
19848 | 281 } |
282 | |
19873 | 283 if (*bm_o) |
19965 | 284 *bm_s = fix_outline_and_shadow(*bm_g, *bm_o); |
285 else | |
286 *bm_s = copy_bitmap(*bm_g); | |
19856 | 287 |
19965 | 288 assert(bm_s); |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
289 return 0; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
290 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
291 |