Mercurial > mplayer.hg
annotate libass/ass_bitmap.c @ 25317:7f3cb5408f28
Fixed VIDIX color bug that was introduced when Radeon VIDIX driver
was synchronized with vidix.sf.net.
The red color was saturating.
Corrected value fixes the issue and restore the color to the level
it used to have before synchronization.
Meaning of the value remains unknow but was retrieved from
register's value of a Radeon 9000 card, so it may need further testing.
Patch by Guillaume Lecerf (foxcore at gmail dot com)
author | ben |
---|---|
date | Mon, 10 Dec 2007 19:27:46 +0000 |
parents | 71b3e04d0555 |
children | 501ea0b13962 |
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 /* |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
4 Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
5 |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
6 This program is free software; you can redistribute it and/or modify |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
7 it under the terms of the GNU General Public License as published by |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
8 the Free Software Foundation; either version 2 of the License, or |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
9 (at your option) any later version. |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
10 |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
11 This program is distributed in the hope that it will be useful, |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
14 GNU General Public License for more details. |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
15 |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
16 You should have received a copy of the GNU General Public License |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
17 along with this program; if not, write to the Free Software |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
19 */ |
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
20 |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
21 #include <stdlib.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
22 #include <string.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
23 #include <math.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
24 #include <assert.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
25 #include <ft2build.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
26 #include FT_GLYPH_H |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
27 |
21026
d138463e820b
Collect all includes of mplayer headers in libass in a single file (mputils.h).
eugeni
parents:
20874
diff
changeset
|
28 #include "mputils.h" |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
29 #include "ass_bitmap.h" |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
30 |
19848 | 31 struct ass_synth_priv_s { |
32 int tmp_w, tmp_h; | |
33 unsigned short* tmp; | |
34 | |
35 int g_r; | |
36 int g_w; | |
37 | |
38 unsigned *g; | |
39 unsigned *gt2; | |
40 }; | |
41 | |
42 static const unsigned int maxcolor = 255; | |
43 static const unsigned base = 256; | |
44 static const double blur_radius = 1.5; | |
45 | |
46 static int generate_tables(ass_synth_priv_t* priv, double radius) | |
47 { | |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
48 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
|
49 int mx, i; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
50 double volume_diff, volume_factor = 0; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
51 unsigned volume; |
19848 | 52 |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
53 priv->g_r = ceil(radius); |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
54 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
|
55 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
56 if (priv->g_r) { |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
57 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
|
58 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
|
59 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
|
60 return -1; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
61 } |
19848 | 62 } |
63 | |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
64 if (priv->g_r) { |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
65 // gaussian curve with volume = 256 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
66 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
|
67 volume_factor+= volume_diff; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
68 volume=0; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
69 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
|
70 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
|
71 volume+= priv->g[i]; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
72 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
73 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
|
74 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
75 volume=0; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
76 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
|
77 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
|
78 volume+= priv->g[i]; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
79 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
80 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
81 // gauss table: |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
82 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
|
83 for(i=0;i<256;i++){ |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
84 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
|
85 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
86 } |
19848 | 87 } |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
88 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
89 return 0; |
19848 | 90 } |
91 | |
92 static void resize_tmp(ass_synth_priv_t* priv, int w, int h) | |
93 { | |
94 if (priv->tmp_w >= w && priv->tmp_h >= h) | |
95 return; | |
96 if (priv->tmp_w == 0) | |
97 priv->tmp_w = 64; | |
98 if (priv->tmp_h == 0) | |
99 priv->tmp_h = 64; | |
100 while (priv->tmp_w < w) priv->tmp_w *= 2; | |
101 while (priv->tmp_h < h) priv->tmp_h *= 2; | |
102 if (priv->tmp) | |
103 free(priv->tmp); | |
104 priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(short)); | |
105 } | |
106 | |
22886 | 107 ass_synth_priv_t* ass_synth_init(void) |
19848 | 108 { |
109 ass_synth_priv_t* priv = calloc(1, sizeof(ass_synth_priv_t)); | |
110 generate_tables(priv, blur_radius); | |
111 return priv; | |
112 } | |
113 | |
114 void ass_synth_done(ass_synth_priv_t* priv) | |
115 { | |
19962 | 116 if (priv->tmp) |
117 free(priv->tmp); | |
118 if (priv->g) | |
119 free(priv->g); | |
120 if (priv->gt2) | |
121 free(priv->gt2); | |
19848 | 122 free(priv); |
123 } | |
124 | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
125 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
|
126 { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
127 bitmap_t* bm; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
128 bm = calloc(1, sizeof(bitmap_t)); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
129 bm->buffer = malloc(w*h); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
130 bm->w = w; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
131 bm->h = h; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
132 bm->left = bm->top = 0; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
133 return bm; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
134 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
135 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
136 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
|
137 { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
138 if (bm) { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
139 if (bm->buffer) free(bm->buffer); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
140 free(bm); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
141 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
142 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
143 |
19965 | 144 static bitmap_t* copy_bitmap(const bitmap_t* src) |
145 { | |
146 bitmap_t* dst = alloc_bitmap(src->w, src->h); | |
147 dst->left = src->left; | |
148 dst->top = src->top; | |
149 memcpy(dst->buffer, src->buffer, src->w * src->h); | |
150 return dst; | |
151 } | |
152 | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
153 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
|
154 { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
155 FT_BitmapGlyph bg; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
156 FT_Bitmap* bit; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
157 bitmap_t* bm; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
158 int w, h; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
159 unsigned char* src; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
160 unsigned char* dst; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
161 int i; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
162 int error; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
163 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
164 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
|
165 if (error) { |
21066 | 166 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
|
167 return 0; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
168 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
169 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
170 bg = (FT_BitmapGlyph)glyph; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
171 bit = &(bg->bitmap); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
172 if (bit->pixel_mode != FT_PIXEL_MODE_GRAY) { |
21066 | 173 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
|
174 FT_Done_Glyph(glyph); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
175 return 0; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
176 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
177 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
178 w = bit->width; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
179 h = bit->rows; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
180 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
|
181 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
|
182 bm->left = bg->left - bord; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
183 bm->top = - bg->top - bord; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
184 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
185 src = bit->buffer; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
186 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
|
187 for (i = 0; i < h; ++i) { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
188 memcpy(dst, src, w); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
189 src += bit->pitch; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
190 dst += bm->w; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
191 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
192 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
193 return bm; |
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 |
19966 | 196 /** |
197 * \brief fix outline bitmap and generate shadow bitmap | |
198 * Two things are done here: | |
199 * 1. Glyph bitmap is subtracted from outline bitmap. This way looks much better in some cases. | |
200 * 2. Shadow bitmap is created as a sum of glyph and outline bitmaps. | |
201 */ | |
19965 | 202 static bitmap_t* fix_outline_and_shadow(bitmap_t* bm_g, bitmap_t* bm_o) |
19856 | 203 { |
204 int x, y; | |
19941
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
205 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
|
206 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
|
207 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
|
208 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 | 209 |
210 bitmap_t* bm_s = copy_bitmap(bm_o); | |
211 | |
19941
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
212 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
|
213 unsigned char* o = bm_o->buffer + (t - bm_o->top) * bm_o->w + (l - bm_o->left); |
19965 | 214 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
|
215 |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
216 for (y = 0; y < b - t; ++y) { |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
217 for (x = 0; x < r - l; ++x) { |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
218 unsigned char c_g, c_o; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
219 c_g = g[x]; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
220 c_o = o[x]; |
20874 | 221 o[x] = (c_o > c_g) ? c_o : 0; |
19965 | 222 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
|
223 } |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
224 g += bm_g->w; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
225 o += bm_o->w; |
19965 | 226 s += bm_s->w; |
19856 | 227 } |
19965 | 228 |
229 assert(bm_s); | |
230 return bm_s; | |
19856 | 231 } |
232 | |
19965 | 233 int glyph_to_bitmap(ass_synth_priv_t* priv, FT_Glyph glyph, FT_Glyph outline_glyph, |
234 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
|
235 { |
19956 | 236 const int bord = be ? ceil(blur_radius) : 0; |
19848 | 237 |
19965 | 238 assert(bm_g && bm_o && bm_s); |
239 | |
240 *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
|
241 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
242 if (glyph) |
19848 | 243 *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
|
244 if (!*bm_g) |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
245 return 1; |
19965 | 246 |
19873 | 247 if (outline_glyph) { |
19848 | 248 *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
|
249 if (!*bm_o) { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
250 ass_free_bitmap(*bm_g); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
251 return 1; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
252 } |
19965 | 253 } |
19873 | 254 if (*bm_o) |
19848 | 255 resize_tmp(priv, (*bm_o)->w, (*bm_o)->h); |
256 resize_tmp(priv, (*bm_g)->w, (*bm_g)->h); | |
257 | |
258 if (be) { | |
259 blur((*bm_g)->buffer, priv->tmp, (*bm_g)->w, (*bm_g)->h, (*bm_g)->w, (int*)priv->gt2, priv->g_r, priv->g_w); | |
19873 | 260 if (*bm_o) |
19848 | 261 blur((*bm_o)->buffer, priv->tmp, (*bm_o)->w, (*bm_o)->h, (*bm_o)->w, (int*)priv->gt2, priv->g_r, priv->g_w); |
262 } | |
263 | |
19873 | 264 if (*bm_o) |
19965 | 265 *bm_s = fix_outline_and_shadow(*bm_g, *bm_o); |
266 else | |
267 *bm_s = copy_bitmap(*bm_g); | |
19856 | 268 |
19965 | 269 assert(bm_s); |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
270 return 0; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
271 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
272 |