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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
4 * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
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
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
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
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
9 * it under the terms of the GNU General Public License as published by
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
10 * the Free Software Foundation; either version 2 of the License, or
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
11 * (at your option) any later version.
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
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
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
16 * GNU General Public License for more details.
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
17 *
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
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
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0f892cd714b2 Use standard license header.
diego
parents: 26035
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
33 struct ass_synth_priv_s {
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
34 int tmp_w, tmp_h;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
35 unsigned short* tmp;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
36
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
37 int g_r;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
38 int g_w;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
39
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
40 unsigned *g;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
41 unsigned *gt2;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
42 };
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
43
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
44 static const unsigned int maxcolor = 255;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
45 static const unsigned base = 256;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
46 static const double blur_radius = 1.5;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
47
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
48 static int generate_tables(ass_synth_priv_t* priv, double radius)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
64 }
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
92 }
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
93
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
94 static void resize_tmp(ass_synth_priv_t* priv, int w, int h)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
95 {
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
96 if (priv->tmp_w >= w && priv->tmp_h >= h)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
97 return;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
98 if (priv->tmp_w == 0)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
99 priv->tmp_w = 64;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
100 if (priv->tmp_h == 0)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
101 priv->tmp_h = 64;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
102 while (priv->tmp_w < w) priv->tmp_w *= 2;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
103 while (priv->tmp_h < h) priv->tmp_h *= 2;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
104 if (priv->tmp)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
105 free(priv->tmp);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
106 priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(short));
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
107 }
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
108
22886
71b3e04d0555 "()" to "(void)" function param list fixes
uau
parents: 21066
diff changeset
109 ass_synth_priv_t* ass_synth_init(void)
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
110 {
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
111 ass_synth_priv_t* priv = calloc(1, sizeof(ass_synth_priv_t));
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
112 generate_tables(priv, blur_radius);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
113 return priv;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
114 }
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
115
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
116 void ass_synth_done(ass_synth_priv_t* priv)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
117 {
19962
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
118 if (priv->tmp)
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
119 free(priv->tmp);
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
120 if (priv->g)
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
121 free(priv->g);
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
122 if (priv->gt2)
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
123 free(priv->gt2);
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
124 free(priv);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
125 }
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
146 static bitmap_t* copy_bitmap(const bitmap_t* src)
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
147 {
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
148 bitmap_t* dst = alloc_bitmap(src->w, src->h);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
149 dst->left = src->left;
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
150 dst->top = src->top;
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
151 memcpy(dst->buffer, src->buffer, src->w * src->h);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
152 return dst;
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
153 }
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
6196ba31e97e MSGTRs for libass
kraymer
parents: 21026
diff changeset
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
6196ba31e97e MSGTRs for libass
kraymer
parents: 21026
diff changeset
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
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
214 /**
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
215 * \brief fix outline bitmap and generate shadow bitmap
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
216 * Two things are done here:
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
217 * 1. Glyph bitmap is subtracted from outline bitmap. This way looks much better in some cases.
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
218 * 2. Shadow bitmap is created as a sum of glyph and outline bitmaps.
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
219 */
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
220 static bitmap_t* fix_outline_and_shadow(bitmap_t* bm_g, bitmap_t* bm_o)
19856
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
221 {
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
227
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
228 bitmap_t* bm_s = copy_bitmap(bm_o);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
b6d87b58754f Partial fix for semitransparent glyph outlines.
eugeni
parents: 20629
diff changeset
239 o[x] = (c_o > c_g) ? c_o : 0;
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
244 s += bm_s->w;
19856
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
245 }
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
246
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
247 assert(bm_s);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
248 return bm_s;
19856
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
249 }
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
250
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
251 int glyph_to_bitmap(ass_synth_priv_t* priv, FT_Glyph glyph, FT_Glyph outline_glyph,
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
5f268ded7f6a Reduce size of non-blurred bitmaps.
eugeni
parents: 19955
diff changeset
254 const int bord = be ? ceil(blur_radius) : 0;
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
255
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
256 assert(bm_g && bm_o && bm_s);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
257
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
264
19873
98d32b832c3a Reduce code duplication in init_render_context().
eugeni
parents: 19856
diff changeset
265 if (outline_glyph) {
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
271 }
19873
98d32b832c3a Reduce code duplication in init_render_context().
eugeni
parents: 19856
diff changeset
272 if (*bm_o)
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
273 resize_tmp(priv, (*bm_o)->w, (*bm_o)->h);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
274 resize_tmp(priv, (*bm_g)->w, (*bm_g)->h);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
275
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
276 if (be) {
19873
98d32b832c3a Reduce code duplication in init_render_context().
eugeni
parents: 19856
diff changeset
277 if (*bm_o)
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
e2de11109139 If (has outline) blur(outline) else blur(glyph).
eugeni
parents: 26738
diff changeset
279 else
e2de11109139 If (has outline) blur(outline) else blur(glyph).
eugeni
parents: 26738
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
281 }
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
282
19873
98d32b832c3a Reduce code duplication in init_render_context().
eugeni
parents: 19856
diff changeset
283 if (*bm_o)
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
284 *bm_s = fix_outline_and_shadow(*bm_g, *bm_o);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
285 else
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
286 *bm_s = copy_bitmap(*bm_g);
19856
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
287
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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