Mercurial > mplayer.hg
annotate libass/ass_bitmap.c @ 20874:b6d87b58754f
Partial fix for semitransparent glyph outlines.
This fix removes semitransparent area (less then pixel width) between glyph and
it's outline. Instead, it makes them overlap a little. It usually looks much
better this way.
Complete fix seems impossible with the current output format (single color
alpha bitmaps). The right way is to blend both glyph and outline into one
bitmap so that 2 pixels with 50% transparency produce a fully solid one.
This requires RGBA bitmap output from libass.
author | eugeni |
---|---|
date | Mon, 13 Nov 2006 16:35:15 +0000 |
parents | e8885ec63928 |
children | d138463e820b |
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 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
28 #include "mp_msg.h" |
20503 | 29 #include "libvo/font_load.h" // for blur() |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
30 #include "ass_bitmap.h" |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
31 |
19848 | 32 struct ass_synth_priv_s { |
33 int tmp_w, tmp_h; | |
34 unsigned short* tmp; | |
35 | |
36 int g_r; | |
37 int g_w; | |
38 | |
39 unsigned *g; | |
40 unsigned *gt2; | |
41 }; | |
42 | |
43 static const unsigned int maxcolor = 255; | |
44 static const unsigned base = 256; | |
45 static const double blur_radius = 1.5; | |
46 | |
47 static int generate_tables(ass_synth_priv_t* priv, double radius) | |
48 { | |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
49 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
|
50 int mx, i; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
51 double volume_diff, volume_factor = 0; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
52 unsigned volume; |
19848 | 53 |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
54 priv->g_r = ceil(radius); |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
55 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
|
56 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
57 if (priv->g_r) { |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
58 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
|
59 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
|
60 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
|
61 return -1; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
62 } |
19848 | 63 } |
64 | |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
65 if (priv->g_r) { |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
66 // gaussian curve with volume = 256 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
67 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
|
68 volume_factor+= volume_diff; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
69 volume=0; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
70 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
|
71 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
|
72 volume+= priv->g[i]; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
73 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
74 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
|
75 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
76 volume=0; |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
77 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
|
78 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
|
79 volume+= priv->g[i]; |
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 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
82 // gauss table: |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
83 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
|
84 for(i=0;i<256;i++){ |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
85 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
|
86 } |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
87 } |
19848 | 88 } |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
89 |
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
90 return 0; |
19848 | 91 } |
92 | |
93 static void resize_tmp(ass_synth_priv_t* priv, int w, int h) | |
94 { | |
95 if (priv->tmp_w >= w && priv->tmp_h >= h) | |
96 return; | |
97 if (priv->tmp_w == 0) | |
98 priv->tmp_w = 64; | |
99 if (priv->tmp_h == 0) | |
100 priv->tmp_h = 64; | |
101 while (priv->tmp_w < w) priv->tmp_w *= 2; | |
102 while (priv->tmp_h < h) priv->tmp_h *= 2; | |
103 if (priv->tmp) | |
104 free(priv->tmp); | |
105 priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(short)); | |
106 } | |
107 | |
108 ass_synth_priv_t* ass_synth_init() | |
109 { | |
110 ass_synth_priv_t* priv = calloc(1, sizeof(ass_synth_priv_t)); | |
111 generate_tables(priv, blur_radius); | |
112 return priv; | |
113 } | |
114 | |
115 void ass_synth_done(ass_synth_priv_t* priv) | |
116 { | |
19962 | 117 if (priv->tmp) |
118 free(priv->tmp); | |
119 if (priv->g) | |
120 free(priv->g); | |
121 if (priv->gt2) | |
122 free(priv->gt2); | |
19848 | 123 free(priv); |
124 } | |
125 | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
126 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
|
127 { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
128 bitmap_t* bm; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
129 bm = calloc(1, sizeof(bitmap_t)); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
130 bm->buffer = malloc(w*h); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
131 bm->w = w; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
132 bm->h = h; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
133 bm->left = bm->top = 0; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
134 return bm; |
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 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
137 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
|
138 { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
139 if (bm) { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
140 if (bm->buffer) free(bm->buffer); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
141 free(bm); |
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 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
144 |
19965 | 145 static bitmap_t* copy_bitmap(const bitmap_t* src) |
146 { | |
147 bitmap_t* dst = alloc_bitmap(src->w, src->h); | |
148 dst->left = src->left; | |
149 dst->top = src->top; | |
150 memcpy(dst->buffer, src->buffer, src->w * src->h); | |
151 return dst; | |
152 } | |
153 | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
154 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
|
155 { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
156 FT_BitmapGlyph bg; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
157 FT_Bitmap* bit; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
158 bitmap_t* bm; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
159 int w, h; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
160 unsigned char* src; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
161 unsigned char* dst; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
162 int i; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
163 int error; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
164 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
165 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
|
166 if (error) { |
20629
e8885ec63928
Introduce MSGT_ASS, use it for all libass messages.
eugeni
parents:
20503
diff
changeset
|
167 mp_msg(MSGT_ASS, MSGL_WARN, "FT_Glyph_To_Bitmap error %d \n", error); |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
168 return 0; |
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 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
171 bg = (FT_BitmapGlyph)glyph; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
172 bit = &(bg->bitmap); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
173 if (bit->pixel_mode != FT_PIXEL_MODE_GRAY) { |
20629
e8885ec63928
Introduce MSGT_ASS, use it for all libass messages.
eugeni
parents:
20503
diff
changeset
|
174 mp_msg(MSGT_ASS, MSGL_WARN, "Unsupported pixel mode: %d\n", (int)(bit->pixel_mode)); |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
175 FT_Done_Glyph(glyph); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
176 return 0; |
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 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
179 w = bit->width; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
180 h = bit->rows; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
181 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
|
182 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
|
183 bm->left = bg->left - bord; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
184 bm->top = - bg->top - bord; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
185 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
186 src = bit->buffer; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
187 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
|
188 for (i = 0; i < h; ++i) { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
189 memcpy(dst, src, w); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
190 src += bit->pitch; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
191 dst += bm->w; |
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 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
194 return bm; |
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 |
19966 | 197 /** |
198 * \brief fix outline bitmap and generate shadow bitmap | |
199 * Two things are done here: | |
200 * 1. Glyph bitmap is subtracted from outline bitmap. This way looks much better in some cases. | |
201 * 2. Shadow bitmap is created as a sum of glyph and outline bitmaps. | |
202 */ | |
19965 | 203 static bitmap_t* fix_outline_and_shadow(bitmap_t* bm_g, bitmap_t* bm_o) |
19856 | 204 { |
205 int x, y; | |
19941
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
206 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
|
207 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
|
208 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
|
209 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 | 210 |
211 bitmap_t* bm_s = copy_bitmap(bm_o); | |
212 | |
19941
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
213 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
|
214 unsigned char* o = bm_o->buffer + (t - bm_o->top) * bm_o->w + (l - bm_o->left); |
19965 | 215 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
|
216 |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
217 for (y = 0; y < b - t; ++y) { |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
218 for (x = 0; x < r - l; ++x) { |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
219 unsigned char c_g, c_o; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
220 c_g = g[x]; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
221 c_o = o[x]; |
20874 | 222 o[x] = (c_o > c_g) ? c_o : 0; |
19965 | 223 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
|
224 } |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
225 g += bm_g->w; |
66d444e5ec8d
Better fix_outline implementation. No more "fix_outline failed" messages,
eugeni
parents:
19873
diff
changeset
|
226 o += bm_o->w; |
19965 | 227 s += bm_s->w; |
19856 | 228 } |
19965 | 229 |
230 assert(bm_s); | |
231 return bm_s; | |
19856 | 232 } |
233 | |
19965 | 234 int glyph_to_bitmap(ass_synth_priv_t* priv, FT_Glyph glyph, FT_Glyph outline_glyph, |
235 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
|
236 { |
19956 | 237 const int bord = be ? ceil(blur_radius) : 0; |
19848 | 238 |
19965 | 239 assert(bm_g && bm_o && bm_s); |
240 | |
241 *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
|
242 |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
243 if (glyph) |
19848 | 244 *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
|
245 if (!*bm_g) |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
246 return 1; |
19965 | 247 |
19873 | 248 if (outline_glyph) { |
19848 | 249 *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
|
250 if (!*bm_o) { |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
251 ass_free_bitmap(*bm_g); |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
252 return 1; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
253 } |
19965 | 254 } |
19873 | 255 if (*bm_o) |
19848 | 256 resize_tmp(priv, (*bm_o)->w, (*bm_o)->h); |
257 resize_tmp(priv, (*bm_g)->w, (*bm_g)->h); | |
258 | |
259 if (be) { | |
260 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 | 261 if (*bm_o) |
19848 | 262 blur((*bm_o)->buffer, priv->tmp, (*bm_o)->w, (*bm_o)->h, (*bm_o)->w, (int*)priv->gt2, priv->g_r, priv->g_w); |
263 } | |
264 | |
19873 | 265 if (*bm_o) |
19965 | 266 *bm_s = fix_outline_and_shadow(*bm_g, *bm_o); |
267 else | |
268 *bm_s = copy_bitmap(*bm_g); | |
19856 | 269 |
19965 | 270 assert(bm_s); |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
271 return 0; |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
272 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
273 |