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
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 /*
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
5cbf1c33a668 Revert r20517.
eugeni
parents: 20501
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
32 struct ass_synth_priv_s {
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
33 int tmp_w, tmp_h;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
34 unsigned short* tmp;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
35
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
36 int g_r;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
37 int g_w;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
38
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
39 unsigned *g;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
40 unsigned *gt2;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
41 };
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 static const unsigned int maxcolor = 255;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
44 static const unsigned base = 256;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
45 static const double blur_radius = 1.5;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
46
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
47 static int generate_tables(ass_synth_priv_t* priv, double radius)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
63 }
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
91 }
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 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
94 {
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
95 if (priv->tmp_w >= w && priv->tmp_h >= h)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
96 return;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
97 if (priv->tmp_w == 0)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
98 priv->tmp_w = 64;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
99 if (priv->tmp_h == 0)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
100 priv->tmp_h = 64;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
101 while (priv->tmp_w < w) priv->tmp_w *= 2;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
102 while (priv->tmp_h < h) priv->tmp_h *= 2;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
103 if (priv->tmp)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
104 free(priv->tmp);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
105 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
106 }
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 ass_synth_priv_t* ass_synth_init()
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
109 {
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
110 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
111 generate_tables(priv, blur_radius);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
112 return priv;
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
113 }
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 void ass_synth_done(ass_synth_priv_t* priv)
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
116 {
19962
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
117 if (priv->tmp)
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
118 free(priv->tmp);
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
119 if (priv->g)
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
120 free(priv->g);
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
121 if (priv->gt2)
c76d6a7332e8 Free memory in ass_synth_done().
eugeni
parents: 19956
diff changeset
122 free(priv->gt2);
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
123 free(priv);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
124 }
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
145 static bitmap_t* copy_bitmap(const bitmap_t* src)
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
146 {
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
147 bitmap_t* dst = alloc_bitmap(src->w, src->h);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
148 dst->left = src->left;
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
149 dst->top = src->top;
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
150 memcpy(dst->buffer, src->buffer, src->w * src->h);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
151 return dst;
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
152 }
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
197 /**
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
198 * \brief fix outline bitmap and generate shadow bitmap
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
199 * Two things are done here:
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
200 * 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
201 * 2. Shadow bitmap is created as a sum of glyph and outline bitmaps.
27187c1ac20b Cosmetics: add some comments.
eugeni
parents: 19965
diff changeset
202 */
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
203 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
204 {
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
210
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
211 bitmap_t* bm_s = copy_bitmap(bm_o);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
b6d87b58754f Partial fix for semitransparent glyph outlines.
eugeni
parents: 20629
diff changeset
222 o[x] = (c_o > c_g) ? c_o : 0;
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
227 s += bm_s->w;
19856
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
228 }
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
229
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
230 assert(bm_s);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
231 return bm_s;
19856
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
232 }
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
233
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
234 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
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
5f268ded7f6a Reduce size of non-blurred bitmaps.
eugeni
parents: 19955
diff changeset
237 const int bord = be ? ceil(blur_radius) : 0;
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
238
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
239 assert(bm_g && bm_o && bm_s);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
240
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
247
19873
98d32b832c3a Reduce code duplication in init_render_context().
eugeni
parents: 19856
diff changeset
248 if (outline_glyph) {
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
254 }
19873
98d32b832c3a Reduce code duplication in init_render_context().
eugeni
parents: 19856
diff changeset
255 if (*bm_o)
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
256 resize_tmp(priv, (*bm_o)->w, (*bm_o)->h);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
257 resize_tmp(priv, (*bm_g)->w, (*bm_g)->h);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
258
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
259 if (be) {
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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
98d32b832c3a Reduce code duplication in init_render_context().
eugeni
parents: 19856
diff changeset
261 if (*bm_o)
19848
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
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);
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
263 }
07be98a5dd5f Add \be (blur edges) support to libass.
eugeni
parents: 19846
diff changeset
264
19873
98d32b832c3a Reduce code duplication in init_render_context().
eugeni
parents: 19856
diff changeset
265 if (*bm_o)
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
266 *bm_s = fix_outline_and_shadow(*bm_g, *bm_o);
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
267 else
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
268 *bm_s = copy_bitmap(*bm_g);
19856
b4cb97ef9d20 Subtract glyph bitmap from outline bitmap.
eugeni
parents: 19848
diff changeset
269
19965
70352570e9ae Shadow support in libass.
eugeni
parents: 19962
diff changeset
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