57 |
57 |
#include FT_SYNTHESIS_H
|
58 |
58 |
#endif
|
59 |
59 |
|
|
60 |
#define FIR_FILTER 1
|
|
61 |
|
60 |
62 |
#if HAVE_FT_LIBRARY_SETLCDFILTER
|
61 |
63 |
#include FT_LCD_FILTER_H
|
62 |
64 |
#endif
|
... | ... | |
607 |
609 |
_cairo_ft_unscaled_font_fini (unscaled);
|
608 |
610 |
}
|
609 |
611 |
|
|
612 |
static const int fir_filter[5] = { 0x1C, 0x38, 0x55, 0x38, 0x1C };
|
|
613 |
|
610 |
614 |
static cairo_bool_t
|
611 |
615 |
_has_unlocked_face (const void *entry)
|
612 |
616 |
{
|
... | ... | |
1114 |
1118 |
unsigned char *data;
|
1115 |
1119 |
int format = CAIRO_FORMAT_A8;
|
1116 |
1120 |
cairo_image_surface_t *image;
|
|
1121 |
cairo_bool_t subpixel = FALSE;
|
1117 |
1122 |
|
1118 |
1123 |
width = bitmap->width;
|
1119 |
1124 |
height = bitmap->rows;
|
... | ... | |
1183 |
1188 |
}
|
1184 |
1189 |
|
1185 |
1190 |
format = CAIRO_FORMAT_A8;
|
1186 |
|
} else {
|
|
1191 |
} else
|
|
1192 |
#ifdef FIR_FILTER
|
|
1193 |
{
|
|
1194 |
unsigned char* line;
|
|
1195 |
unsigned char* bufBitmap;
|
|
1196 |
int pitch;
|
|
1197 |
unsigned char *data_rgba;
|
|
1198 |
unsigned int width_rgba, stride_rgba;
|
|
1199 |
int vmul = 1;
|
|
1200 |
int hmul = 1;
|
|
1201 |
|
|
1202 |
switch (font_options->subpixel_order) {
|
|
1203 |
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
|
1204 |
case CAIRO_SUBPIXEL_ORDER_RGB:
|
|
1205 |
case CAIRO_SUBPIXEL_ORDER_BGR:
|
|
1206 |
default:
|
|
1207 |
width /= 3;
|
|
1208 |
hmul = 3;
|
|
1209 |
break;
|
|
1210 |
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
|
1211 |
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
|
1212 |
vmul = 3;
|
|
1213 |
height /= 3;
|
|
1214 |
break;
|
|
1215 |
}
|
|
1216 |
/*
|
|
1217 |
* Filter the glyph to soften the color fringes
|
|
1218 |
*/
|
|
1219 |
width_rgba = width;
|
|
1220 |
stride = bitmap->pitch;
|
|
1221 |
stride_rgba = (width_rgba * 4 + 3) & ~3;
|
|
1222 |
data_rgba = calloc (1, stride_rgba * height);
|
|
1223 |
|
|
1224 |
/* perform in-place FIR filtering in either the horizontal or
|
|
1225 |
* vertical direction. We're going to modify the RGB graymap,
|
|
1226 |
* but that's ok, because we either own it, or its part of
|
|
1227 |
* the FreeType glyph slot, which will not be used anymore.
|
|
1228 |
*/
|
|
1229 |
pitch = bitmap->pitch;
|
|
1230 |
line = (unsigned char*)bitmap->buffer;
|
|
1231 |
if ( pitch < 0 )
|
|
1232 |
line -= pitch*(height-1);
|
|
1233 |
|
|
1234 |
bufBitmap = line;
|
|
1235 |
|
|
1236 |
switch (font_options->subpixel_order) {
|
|
1237 |
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
|
1238 |
case CAIRO_SUBPIXEL_ORDER_RGB:
|
|
1239 |
case CAIRO_SUBPIXEL_ORDER_BGR:
|
|
1240 |
{
|
|
1241 |
int h;
|
|
1242 |
|
|
1243 |
for ( h = height; h > 0; h--, line += pitch ) {
|
|
1244 |
int pix[6] = { 0, 0, 0, 0, 0, 0 };
|
|
1245 |
unsigned char* p = line;
|
|
1246 |
unsigned char* limit = line + width*3;
|
|
1247 |
int nn, val, val2;
|
|
1248 |
|
|
1249 |
val = p[0];
|
|
1250 |
for (nn = 0; nn < 3; nn++)
|
|
1251 |
pix[2 + nn] += val * fir_filter[nn];
|
|
1252 |
|
|
1253 |
val = p[1];
|
|
1254 |
for (nn = 0; nn < 4; nn++)
|
|
1255 |
pix[1 + nn] += val * fir_filter[nn];
|
|
1256 |
|
|
1257 |
p += 2;
|
|
1258 |
|
|
1259 |
for ( ; p < limit; p++ ) {
|
|
1260 |
val = p[0];
|
|
1261 |
for (nn = 0; nn < 5; nn++)
|
|
1262 |
pix[nn] += val * fir_filter[nn];
|
|
1263 |
|
|
1264 |
val2 = pix[0] / 256;
|
|
1265 |
val2 |= -(val2 >> 8);
|
|
1266 |
p[-2] = (unsigned char)val2;
|
|
1267 |
|
|
1268 |
for (nn = 0; nn < 5; nn++)
|
|
1269 |
pix[nn] = pix[nn + 1];
|
|
1270 |
}
|
|
1271 |
for (nn = 0; nn < 2; nn++ ) {
|
|
1272 |
val2 = pix[nn] / 256;
|
|
1273 |
val2 |= -(val2 >> 8);
|
|
1274 |
p[nn - 2] = (unsigned char)val2;
|
|
1275 |
}
|
|
1276 |
}
|
|
1277 |
}
|
|
1278 |
break;
|
|
1279 |
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
|
1280 |
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
|
1281 |
{
|
|
1282 |
int w;
|
|
1283 |
|
|
1284 |
for (w = 0; w < width; w++ ) {
|
|
1285 |
int pix[6] = { 0, 0, 0, 0, 0, 0 };
|
|
1286 |
unsigned char* p = bufBitmap + w;
|
|
1287 |
unsigned char* limit = bufBitmap + w + height*3*pitch;
|
|
1288 |
int nn, val, val2;
|
|
1289 |
|
|
1290 |
val = p[0];
|
|
1291 |
for (nn = 0; nn < 3; nn++)
|
|
1292 |
pix[2 + nn] += val*fir_filter[nn];
|
|
1293 |
|
|
1294 |
val = p[pitch];
|
|
1295 |
for (nn = 0; nn < 4; nn++ )
|
|
1296 |
pix[1 + nn] += val * fir_filter[nn];
|
|
1297 |
|
|
1298 |
p += 2*pitch;
|
|
1299 |
for ( ; p < limit; p += pitch ) {
|
|
1300 |
val = p[0];
|
|
1301 |
for (nn = 0; nn < 5; nn++ )
|
|
1302 |
pix[nn] += val * fir_filter[nn];
|
|
1303 |
|
|
1304 |
val2 = pix[0] / 256;
|
|
1305 |
val2 |= -(val2 >> 8);
|
|
1306 |
p[-2 * pitch] = (unsigned char)val2;
|
|
1307 |
|
|
1308 |
for (nn = 0; nn < 5; nn++)
|
|
1309 |
pix[nn] = pix[nn+1];
|
|
1310 |
}
|
|
1311 |
|
|
1312 |
for (nn = 0; nn < 2; nn++) {
|
|
1313 |
val2 = pix[nn] / 256;
|
|
1314 |
val2 |= -(val2 >> 8);
|
|
1315 |
p[(nn - 2) * pitch] = (unsigned char)val2;
|
|
1316 |
}
|
|
1317 |
}
|
|
1318 |
}
|
|
1319 |
break;
|
|
1320 |
default: /* shouldn't happen */
|
|
1321 |
break;
|
|
1322 |
}
|
|
1323 |
|
|
1324 |
/* now copy the resulting graymap into an ARGB32 image */
|
|
1325 |
{
|
|
1326 |
unsigned char* in_line = bufBitmap;
|
|
1327 |
unsigned char* out_line = data_rgba;
|
|
1328 |
int h = height;
|
|
1329 |
|
|
1330 |
switch (font_options->subpixel_order) {
|
|
1331 |
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
|
1332 |
case CAIRO_SUBPIXEL_ORDER_RGB:
|
|
1333 |
for ( ; h > 0; h--, in_line += pitch, out_line += stride_rgba) {
|
|
1334 |
unsigned char* in = in_line;
|
|
1335 |
int* out = (int*)out_line;
|
|
1336 |
int w;
|
|
1337 |
|
|
1338 |
for (w = width; w > 0; w--, in += 3, out += 1) {
|
|
1339 |
int r = in[0];
|
|
1340 |
int g = in[1];
|
|
1341 |
int b = in[2];
|
|
1342 |
|
|
1343 |
out[0] = (g << 24) | (r << 16) | (g << 8) | b;
|
|
1344 |
}
|
|
1345 |
}
|
|
1346 |
break;
|
|
1347 |
case CAIRO_SUBPIXEL_ORDER_BGR:
|
|
1348 |
for ( ; h > 0; h--, in_line += pitch, out_line += stride_rgba) {
|
|
1349 |
unsigned char* in = in_line;
|
|
1350 |
int* out = (int*)out_line;
|
|
1351 |
int w;
|
|
1352 |
|
|
1353 |
for (w = width; w > 0; w--, in += 3, out += 1) {
|
|
1354 |
int r = in[2];
|
|
1355 |
int g = in[1];
|
|
1356 |
int b = in[0];
|
|
1357 |
|
|
1358 |
out[0] = (g << 24) | (r << 16) | (g << 8) | b;
|
|
1359 |
}
|
|
1360 |
}
|
|
1361 |
break;
|
|
1362 |
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
|
1363 |
for ( ; h > 0; h--, in_line += pitch*3, out_line += stride_rgba) {
|
|
1364 |
unsigned char* in = in_line;
|
|
1365 |
int* out = (int*)out_line;
|
|
1366 |
int w;
|
|
1367 |
|
|
1368 |
for (w = width; w > 0; w--, in += 1, out += 1) {
|
|
1369 |
int r = in[0];
|
|
1370 |
int g = in[pitch];
|
|
1371 |
int b = in[pitch*2];
|
|
1372 |
|
|
1373 |
out[0] = (g << 24) | (r << 16) | (g << 8) | b;
|
|
1374 |
}
|
|
1375 |
}
|
|
1376 |
break;
|
|
1377 |
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
|
1378 |
for ( ; h > 0; h--, in_line += pitch*3, out_line += stride_rgba) {
|
|
1379 |
unsigned char* in = in_line;
|
|
1380 |
int* out = (int*)out_line;
|
|
1381 |
int w;
|
|
1382 |
|
|
1383 |
for (w = width; w > 0; w--, in += 1, out += 1) {
|
|
1384 |
int r = in[2*pitch];
|
|
1385 |
int g = in[pitch];
|
|
1386 |
int b = in[0];
|
|
1387 |
|
|
1388 |
out[0] = (g << 24) | (r << 16) | (g << 8) | b;
|
|
1389 |
}
|
|
1390 |
}
|
|
1391 |
break;
|
|
1392 |
}
|
|
1393 |
}
|
|
1394 |
|
|
1395 |
if (own_buffer)
|
|
1396 |
free (bitmap->buffer);
|
|
1397 |
data = data_rgba;
|
|
1398 |
stride = stride_rgba;
|
|
1399 |
format = CAIRO_FORMAT_ARGB32;
|
|
1400 |
subpixel = TRUE;
|
|
1401 |
break;
|
|
1402 |
}
|
|
1403 |
#else /* !FIR_FILTER */
|
|
1404 |
{
|
1187 |
1405 |
/* if we get there, the data from the source bitmap
|
1188 |
1406 |
* really comes from _fill_xrender_bitmap, and is
|
1189 |
1407 |
* made of 32-bit ARGB or ABGR values */
|
... | ... | |
1194 |
1412 |
stride = bitmap->pitch;
|
1195 |
1413 |
format = CAIRO_FORMAT_ARGB32;
|
1196 |
1414 |
}
|
|
1415 |
#endif /* !FIR_FILTER */
|
1197 |
1416 |
break;
|
1198 |
1417 |
case FT_PIXEL_MODE_GRAY2:
|
1199 |
1418 |
case FT_PIXEL_MODE_GRAY4:
|
... | ... | |
1244 |
1463 |
cairo_font_options_t *font_options,
|
1245 |
1464 |
cairo_image_surface_t **surface)
|
1246 |
1465 |
{
|
1247 |
|
int rgba = FC_RGBA_UNKNOWN;
|
1248 |
|
int lcd_filter = FT_LCD_FILTER_LEGACY;
|
1249 |
|
FT_GlyphSlot glyphslot = face->glyph;
|
|
1466 |
FT_GlyphSlot glyphslot = face->glyph;
|
1250 |
1467 |
FT_Outline *outline = &glyphslot->outline;
|
1251 |
1468 |
FT_Bitmap bitmap;
|
1252 |
1469 |
FT_BBox cbox;
|
1253 |
|
unsigned int width, height;
|
|
1470 |
FT_Matrix matrix;
|
|
1471 |
int hmul = 1;
|
|
1472 |
int vmul = 1;
|
|
1473 |
unsigned int width, height, stride;
|
|
1474 |
cairo_bool_t subpixel = FALSE;
|
1254 |
1475 |
cairo_status_t status;
|
1255 |
|
FT_Error fterror;
|
1256 |
|
FT_Library library = glyphslot->library;
|
1257 |
|
FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL;
|
1258 |
|
|
1259 |
|
switch (font_options->antialias) {
|
1260 |
|
case CAIRO_ANTIALIAS_NONE:
|
1261 |
|
render_mode = FT_RENDER_MODE_MONO;
|
1262 |
|
break;
|
1263 |
|
|
1264 |
|
case CAIRO_ANTIALIAS_SUBPIXEL:
|
1265 |
|
switch (font_options->subpixel_order) {
|
1266 |
|
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
1267 |
|
case CAIRO_SUBPIXEL_ORDER_RGB:
|
1268 |
|
case CAIRO_SUBPIXEL_ORDER_BGR:
|
1269 |
|
render_mode = FT_RENDER_MODE_LCD;
|
1270 |
|
break;
|
1271 |
|
|
1272 |
|
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
1273 |
|
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
1274 |
|
render_mode = FT_RENDER_MODE_LCD_V;
|
1275 |
|
break;
|
1276 |
|
}
|
1277 |
|
|
1278 |
|
switch (font_options->lcd_filter) {
|
1279 |
|
case CAIRO_LCD_FILTER_NONE:
|
1280 |
|
lcd_filter = FT_LCD_FILTER_NONE;
|
1281 |
|
break;
|
1282 |
|
case CAIRO_LCD_FILTER_DEFAULT:
|
1283 |
|
case CAIRO_LCD_FILTER_INTRA_PIXEL:
|
1284 |
|
lcd_filter = FT_LCD_FILTER_LEGACY;
|
1285 |
|
break;
|
1286 |
|
case CAIRO_LCD_FILTER_FIR3:
|
1287 |
|
lcd_filter = FT_LCD_FILTER_LIGHT;
|
1288 |
|
break;
|
1289 |
|
case CAIRO_LCD_FILTER_FIR5:
|
1290 |
|
lcd_filter = FT_LCD_FILTER_DEFAULT;
|
1291 |
|
break;
|
1292 |
|
}
|
1293 |
|
|
1294 |
|
break;
|
1295 |
|
|
1296 |
|
case CAIRO_ANTIALIAS_DEFAULT:
|
1297 |
|
case CAIRO_ANTIALIAS_GRAY:
|
1298 |
|
render_mode = FT_RENDER_MODE_NORMAL;
|
1299 |
|
}
|
1300 |
1476 |
|
1301 |
1477 |
FT_Outline_Get_CBox (outline, &cbox);
|
1302 |
1478 |
|
... | ... | |
1307 |
1483 |
|
1308 |
1484 |
width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
|
1309 |
1485 |
height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
|
|
1486 |
stride = (width * hmul + 3) & ~3;
|
1310 |
1487 |
|
1311 |
1488 |
if (width * height == 0) {
|
1312 |
1489 |
cairo_format_t format;
|
1313 |
1490 |
/* Looks like fb handles zero-sized images just fine */
|
1314 |
|
switch (render_mode) {
|
1315 |
|
case FT_RENDER_MODE_MONO:
|
|
1491 |
switch (font_options->antialias) {
|
|
1492 |
case CAIRO_ANTIALIAS_NONE:
|
1316 |
1493 |
format = CAIRO_FORMAT_A1;
|
1317 |
1494 |
break;
|
1318 |
|
case FT_RENDER_MODE_LCD:
|
1319 |
|
case FT_RENDER_MODE_LCD_V:
|
|
1495 |
case CAIRO_ANTIALIAS_SUBPIXEL:
|
1320 |
1496 |
format= CAIRO_FORMAT_ARGB32;
|
1321 |
1497 |
break;
|
1322 |
|
case FT_RENDER_MODE_LIGHT:
|
1323 |
|
case FT_RENDER_MODE_NORMAL:
|
1324 |
|
case FT_RENDER_MODE_MAX:
|
|
1498 |
case CAIRO_ANTIALIAS_DEFAULT:
|
|
1499 |
case CAIRO_ANTIALIAS_GRAY:
|
1325 |
1500 |
default:
|
1326 |
1501 |
format = CAIRO_FORMAT_A8;
|
1327 |
1502 |
break;
|
... | ... | |
1331 |
1506 |
cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
|
1332 |
1507 |
if ((*surface)->base.status)
|
1333 |
1508 |
return (*surface)->base.status;
|
1334 |
|
} else {
|
|
1509 |
} else {
|
1335 |
1510 |
|
1336 |
|
int bitmap_size;
|
|
1511 |
matrix.xx = matrix.yy = 0x10000L;
|
|
1512 |
matrix.xy = matrix.yx = 0;
|
1337 |
1513 |
|
1338 |
|
switch (render_mode) {
|
1339 |
|
case FT_RENDER_MODE_LCD:
|
1340 |
|
if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_BGR) {
|
1341 |
|
rgba = FC_RGBA_BGR;
|
1342 |
|
} else {
|
1343 |
|
rgba = FC_RGBA_RGB;
|
1344 |
|
}
|
1345 |
|
case FT_RENDER_MODE_LCD_V:
|
1346 |
|
if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_VBGR) {
|
1347 |
|
rgba = FC_RGBA_VBGR;
|
1348 |
|
} else {
|
1349 |
|
rgba = FC_RGBA_VRGB;
|
1350 |
|
}
|
1351 |
|
break;
|
1352 |
|
case FT_RENDER_MODE_MONO:
|
1353 |
|
case FT_RENDER_MODE_LIGHT:
|
1354 |
|
case FT_RENDER_MODE_NORMAL:
|
1355 |
|
case FT_RENDER_MODE_MAX:
|
1356 |
|
default:
|
|
1514 |
switch (font_options->antialias) {
|
|
1515 |
case CAIRO_ANTIALIAS_NONE:
|
|
1516 |
bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
|
|
1517 |
bitmap.num_grays = 1;
|
|
1518 |
stride = ((width + 31) & -32) >> 3;
|
|
1519 |
break;
|
|
1520 |
case CAIRO_ANTIALIAS_DEFAULT:
|
|
1521 |
case CAIRO_ANTIALIAS_GRAY:
|
|
1522 |
bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
|
|
1523 |
bitmap.num_grays = 256;
|
|
1524 |
stride = (width + 3) & -4;
|
1357 |
1525 |
break;
|
1358 |
|
}
|
1359 |
|
|
1360 |
|
#if HAVE_FT_LIBRARY_SETLCDFILTER
|
1361 |
|
FT_Library_SetLcdFilter (library, lcd_filter);
|
|
1526 |
case CAIRO_ANTIALIAS_SUBPIXEL:
|
|
1527 |
switch (font_options->subpixel_order) {
|
|
1528 |
case CAIRO_SUBPIXEL_ORDER_RGB:
|
|
1529 |
case CAIRO_SUBPIXEL_ORDER_BGR:
|
|
1530 |
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
|
1531 |
default:
|
|
1532 |
matrix.xx *= 3;
|
|
1533 |
hmul = 3;
|
|
1534 |
subpixel = TRUE;
|
|
1535 |
#ifdef FIR_FILTER
|
|
1536 |
cbox.xMin -= 64;
|
|
1537 |
cbox.xMax += 64;
|
|
1538 |
width += 2;
|
1362 |
1539 |
#endif
|
1363 |
|
|
1364 |
|
fterror = FT_Render_Glyph (face->glyph, render_mode);
|
1365 |
|
|
1366 |
|
#if HAVE_FT_LIBRARY_SETLCDFILTER
|
1367 |
|
FT_Library_SetLcdFilter (library, FT_LCD_FILTER_NONE);
|
|
1540 |
break;
|
|
1541 |
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
|
1542 |
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
|
1543 |
matrix.yy *= 3;
|
|
1544 |
vmul = 3;
|
|
1545 |
subpixel = TRUE;
|
|
1546 |
#ifdef FIR_FILTER
|
|
1547 |
cbox.yMin -= 64;
|
|
1548 |
cbox.yMax += 64;
|
|
1549 |
height += 2;
|
1368 |
1550 |
#endif
|
|
1551 |
break;
|
|
1552 |
}
|
|
1553 |
FT_Outline_Transform (outline, &matrix);
|
1369 |
1554 |
|
1370 |
|
if (fterror != 0)
|
1371 |
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
1555 |
bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
|
|
1556 |
bitmap.num_grays = 256;
|
|
1557 |
stride = (width * hmul + 3) & -4;
|
|
1558 |
}
|
1372 |
1559 |
|
1373 |
|
bitmap_size = _compute_xrender_bitmap_size (&bitmap,
|
1374 |
|
face->glyph,
|
1375 |
|
render_mode);
|
1376 |
|
if (bitmap_size < 0)
|
|
1560 |
bitmap.pitch = stride;
|
|
1561 |
bitmap.width = width * hmul;
|
|
1562 |
bitmap.rows = height * vmul;
|
|
1563 |
bitmap.buffer = calloc (stride, bitmap.rows);
|
|
1564 |
if (bitmap.buffer == NULL)
|
1377 |
1565 |
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
1378 |
1566 |
|
1379 |
|
bitmap.buffer = calloc (1, bitmap_size);
|
1380 |
|
if (bitmap.buffer == NULL)
|
1381 |
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
1567 |
FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
|
1382 |
1568 |
|
1383 |
|
_fill_xrender_bitmap (&bitmap, face->glyph, render_mode,
|
1384 |
|
(rgba == FC_RGBA_BGR || rgba == FC_RGBA_VBGR));
|
|
1569 |
if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
|
|
1570 |
free (bitmap.buffer);
|
|
1571 |
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
1572 |
}
|
1385 |
1573 |
|
1386 |
|
/* Note:
|
1387 |
|
* _get_bitmap_surface will free bitmap.buffer if there is an error
|
1388 |
|
*/
|
1389 |
1574 |
status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
|
1390 |
|
if (unlikely (status))
|
|
1575 |
if (status)
|
1391 |
1576 |
return status;
|
1392 |
|
|
1393 |
|
/* Note: the font's coordinate system is upside down from ours, so the
|
1394 |
|
* Y coordinate of the control box needs to be negated. Moreover, device
|
1395 |
|
* offsets are position of glyph origin relative to top left while xMin
|
1396 |
|
* and yMax are offsets of top left relative to origin. Another negation.
|
1397 |
|
*/
|
1398 |
|
cairo_surface_set_device_offset (&(*surface)->base,
|
1399 |
|
(double)-glyphslot->bitmap_left,
|
1400 |
|
(double)+glyphslot->bitmap_top);
|
1401 |
1577 |
}
|
1402 |
1578 |
|
|
1579 |
/*
|
|
1580 |
* Note: the font's coordinate system is upside down from ours, so the
|
|
1581 |
* Y coordinate of the control box needs to be negated. Moreover, device
|
|
1582 |
* offsets are position of glyph origin relative to top left while xMin
|
|
1583 |
* and yMax are offsets of top left relative to origin. Another negation.
|
|
1584 |
*/
|
|
1585 |
cairo_surface_set_device_offset (&(*surface)->base,
|
|
1586 |
floor (-(double) cbox.xMin / 64.0),
|
|
1587 |
floor (+(double) cbox.yMax / 64.0));
|
|
1588 |
|
1403 |
1589 |
return CAIRO_STATUS_SUCCESS;
|
1404 |
1590 |
}
|
1405 |
1591 |
|