Ignore:
Timestamp:
Aug 27, 2010, 11:00:52 AM (11 years ago)
Author:
Silvan Scherrer
Message:

poppler update to 0.14.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/poppler/mypoppler/poppler/CairoOutputDev.cc

    r290 r461  
    1919// Copyright (C) 2005, 2009 Albert Astals Cid <aacid@kde.org>
    2020// Copyright (C) 2005 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
    21 // Copyright (C) 2006-2009 Carlos Garcia Campos <carlosgc@gnome.org>
     21// Copyright (C) 2006-2010 Carlos Garcia Campos <carlosgc@gnome.org>
    2222// Copyright (C) 2008 Carl Worth <cworth@cworth.org>
    23 // Copyright (C) 2008, 2009 Adrian Johnson <ajohnson@redneon.com>
     23// Copyright (C) 2008-2010 Adrian Johnson <ajohnson@redneon.com>
    2424// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
    2525// Copyright (C) 2008, 2009 Chris Wilson <chris@chris-wilson.co.uk>
    2626// Copyright (C) 2008 Hib Eris <hib@hiberis.nl>
    27 // Copyright (C) 2009 David Benjamin <davidben@mit.edu>
     27// Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu>
    2828//
    2929// To see a description of the changes please see the Changelog file that
     
    5959#include "CairoOutputDev.h"
    6060#include "CairoFontEngine.h"
     61#include "CairoRescaleBox.h"
    6162//------------------------------------------------------------------------
    6263
     
    124125  glyphs = NULL;
    125126  fill_pattern = NULL;
     127  fill_color.r = fill_color.g = fill_color.b = 0;
    126128  stroke_pattern = NULL;
     129  stroke_color.r = stroke_color.g = stroke_color.b = 0;
    127130  stroke_opacity = 1.0;
    128131  fill_opacity = 1.0;
     
    224227  /* set up some per page defaults */
    225228  cairo_pattern_destroy(fill_pattern);
     229  cairo_pattern_destroy(stroke_pattern);
     230
    226231  fill_pattern = cairo_pattern_create_rgb(0., 0., 0.);
    227 
    228   cairo_pattern_destroy(stroke_pattern);
    229   stroke_pattern = cairo_pattern_create_rgb(0., 0., 0.);
     232  stroke_pattern = cairo_pattern_reference(fill_pattern);
    230233
    231234  if (text)
     
    270273
    271274  MaskStack* ms = maskStack;
    272   if (mask)
    273     cairo_pattern_destroy(mask);
    274 
    275275  if (ms) {
     276    if (mask)
     277      cairo_pattern_destroy(mask);
    276278    mask = ms->mask;
    277279    maskStack = ms->next;
     
    419421
    420422void CairoOutputDev::updateFillColor(GfxState *state) {
     423  GfxRGB color = fill_color;
     424
    421425  state->getFillRGB(&fill_color);
    422 
    423   cairo_pattern_destroy(fill_pattern);
    424   fill_pattern = cairo_pattern_create_rgba(fill_color.r / 65535.0,
    425                                            fill_color.g / 65535.0,
    426                                            fill_color.b / 65535.0,
    427                                            fill_opacity);
    428 
    429   LOG(printf ("fill color: %d %d %d\n",
    430               fill_color.r, fill_color.g, fill_color.b));
     426  if (color.r != fill_color.r ||
     427      color.g != fill_color.g ||
     428      color.b != fill_color.b)
     429  {
     430    cairo_pattern_destroy(fill_pattern);
     431    fill_pattern = cairo_pattern_create_rgba(colToDbl(fill_color.r),
     432                                             colToDbl(fill_color.g),
     433                                             colToDbl(fill_color.b),
     434                                             fill_opacity);
     435
     436    LOG(printf ("fill color: %d %d %d\n",
     437                fill_color.r, fill_color.g, fill_color.b));
     438  }
    431439}
    432440
    433441void CairoOutputDev::updateStrokeColor(GfxState *state) {
     442  GfxRGB color = stroke_color;
     443
    434444  state->getStrokeRGB(&stroke_color);
    435 
    436   cairo_pattern_destroy(stroke_pattern);
    437   stroke_pattern = cairo_pattern_create_rgba(stroke_color.r / 65535.0,
    438                                              stroke_color.g / 65535.0,
    439                                              stroke_color.b / 65535.0,
    440                                              stroke_opacity);
    441  
    442   LOG(printf ("stroke color: %d %d %d\n",
    443               stroke_color.r, stroke_color.g, stroke_color.b));
     445  if (color.r != stroke_color.r ||
     446      color.g != stroke_color.g ||
     447      color.b != stroke_color.b)
     448  {
     449    cairo_pattern_destroy(stroke_pattern);
     450    stroke_pattern = cairo_pattern_create_rgba(colToDbl(stroke_color.r),
     451                                               colToDbl(stroke_color.g),
     452                                               colToDbl(stroke_color.b),
     453                                               stroke_opacity);
     454
     455    LOG(printf ("stroke color: %d %d %d\n",
     456                stroke_color.r, stroke_color.g, stroke_color.b));
     457  }
    444458}
    445459
    446460void CairoOutputDev::updateFillOpacity(GfxState *state) {
     461  double opacity = fill_opacity;
     462
    447463  fill_opacity = state->getFillOpacity();
    448 
    449   cairo_pattern_destroy(fill_pattern);
    450   fill_pattern = cairo_pattern_create_rgba(fill_color.r / 65535.0,
    451                                            fill_color.g / 65535.0,
    452                                            fill_color.b / 65535.0,
    453                                            fill_opacity);
    454 
    455   LOG(printf ("fill opacity: %f\n", fill_opacity));
     464  if (opacity != fill_opacity) {
     465    cairo_pattern_destroy(fill_pattern);
     466    fill_pattern = cairo_pattern_create_rgba(colToDbl(fill_color.r),
     467                                             colToDbl(fill_color.g),
     468                                             colToDbl(fill_color.b),
     469                                             fill_opacity);
     470
     471    LOG(printf ("fill opacity: %f\n", fill_opacity));
     472  }
    456473}
    457474
    458475void CairoOutputDev::updateStrokeOpacity(GfxState *state) {
     476  double opacity = stroke_opacity;
     477
    459478  stroke_opacity = state->getStrokeOpacity();
    460 
    461   cairo_pattern_destroy(stroke_pattern);
    462   stroke_pattern = cairo_pattern_create_rgba(stroke_color.r / 65535.0,
    463                                              stroke_color.g / 65535.0,
    464                                              stroke_color.b / 65535.0,
    465                                              stroke_opacity);
    466  
    467   LOG(printf ("stroke opacity: %f\n", stroke_opacity));
     479  if (opacity != stroke_opacity) {
     480    cairo_pattern_destroy(stroke_pattern);
     481    stroke_pattern = cairo_pattern_create_rgba(colToDbl(stroke_color.r),
     482                                               colToDbl(stroke_color.g),
     483                                               colToDbl(stroke_color.b),
     484                                               stroke_opacity);
     485
     486    LOG(printf ("stroke opacity: %f\n", stroke_opacity));
     487  }
    468488}
    469489
     
    472492
    473493  cairo_pattern_add_color_stop_rgba(fill_pattern, offset,
    474                                     fill_color.r / 65535.0,
    475                                     fill_color.g / 65535.0,
    476                                     fill_color.b / 65535.0,
     494                                    colToDbl(fill_color.r),
     495                                    colToDbl(fill_color.g),
     496                                    colToDbl(fill_color.b),
    477497                                    fill_opacity);
    478498  LOG(printf ("fill color stop: %f (%d, %d, %d)\n",
     
    481501
    482502void CairoOutputDev::updateBlendMode(GfxState *state) {
    483 #ifdef CAIRO_HAS_BLEND_MODES
     503#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
    484504  switch (state->getBlendMode()) {
    485505  default:
     
    534554  }
    535555  LOG(printf ("blend mode: %d\n", (int)state->getBlendMode()));
    536 #endif /* CAIRO_HAS_BLEND_MODES */
     556#endif /* CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4) */
    537557}
    538558
     
    599619  GfxSubpath *subpath;
    600620  int i, j;
     621  cairo_new_path (cairo);
    601622  for (i = 0; i < path->getNumSubpaths(); ++i) {
    602623    subpath = path->getSubpath(i);
     
    626647
    627648void CairoOutputDev::stroke(GfxState *state) {
     649  if (inType3Char) {
     650      GfxGray gray;
     651      state->getFillGray(&gray);
     652      if (colToDbl(gray) > 0.5)
     653          return;
     654  }
     655
    628656  doPath (cairo, state, state->getPath());
    629657  cairo_set_source (cairo, stroke_pattern);
     
    637665
    638666void CairoOutputDev::fill(GfxState *state) {
     667  if (inType3Char) {
     668      GfxGray gray;
     669      state->getFillGray(&gray);
     670      if (colToDbl(gray) > 0.5)
     671          return;
     672  }
     673
    639674  doPath (cairo, state, state->getPath());
    640675  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);
     
    642677  LOG(printf ("fill\n"));
    643678  //XXX: how do we get the path
    644   cairo_fill (cairo);
     679  if (mask) {
     680    cairo_clip (cairo);
     681    cairo_mask (cairo, mask);
     682  } else {
     683    cairo_fill (cairo);
     684  }
    645685  if (cairo_shape) {
    646686    cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_WINDING);
     
    678718  cairo_t *old_cairo;
    679719  double xMin, yMin, xMax, yMax;
    680 
    681   if (xStep != bbox[2] || yStep != bbox[3])
     720  double width, height;
     721  int surface_width, surface_height;
     722
     723  width = bbox[2] - bbox[0];
     724  height = bbox[3] - bbox[1];
     725
     726  if (xStep != width || yStep != height)
    682727    return gFalse;
    683728  /* TODO: implement the other cases here too */
    684729
     730  surface_width = (int) ceil (width);
     731  surface_height = (int) ceil (height);
     732
    685733  surface = cairo_surface_create_similar (cairo_get_target (cairo),
    686734                                          CAIRO_CONTENT_COLOR_ALPHA,
    687                                           bbox[2], bbox[3]);
     735                                          surface_width, surface_height);
    688736  if (cairo_surface_status (surface))
    689737    return gFalse;
     
    707755  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
    708756  cairo_rectangle (cairo, xMin, yMin, xMax - xMin, yMax - yMin);
     757
     758  cairo_matrix_init_scale (&matrix, surface_width / width, surface_height / height);
     759  cairo_pattern_set_matrix (pattern, &matrix);
    709760
    710761  cairo_matrix_init (&matrix, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
     
    734785  else
    735786    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_PAD);
     787
     788  LOG (printf ("axial-sh\n"));
    736789
    737790  // TODO: use the actual stops in the shading in the case
     
    765818    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_NONE);
    766819
     820  LOG (printf ("radial-sh\n"));
     821
    767822  return gFalse;
    768823}
     
    796851  }
    797852
     853}
     854
     855void CairoOutputDev::clipToStrokePath(GfxState *state) {
     856  LOG(printf("clip-to-stroke-path\n"));
    798857}
    799858
     
    10661125  css->next = groupColorSpaceStack;
    10671126  groupColorSpaceStack = css;
     1127
     1128  LOG(printf ("begin transparency group. knockout: %s\n", knockout ? "yes":"no"));
     1129
    10681130  if (knockout) {
    10691131    knockoutCount++;
     
    11031165
    11041166void CairoOutputDev::endTransparencyGroup(GfxState * /*state*/) {
    1105 
    11061167  if (group)
    11071168    cairo_pattern_destroy(group);
    11081169  group = cairo_pop_group (cairo);
     1170
     1171  LOG(printf ("end transparency group\n"));
    11091172
    11101173  if (groupColorSpaceStack->next && groupColorSpaceStack->next->knockout) {
     
    11171180void CairoOutputDev::paintTransparencyGroup(GfxState * /*state*/, double * /*bbox*/) {
    11181181  cairo_set_source (cairo, group);
     1182
     1183  LOG(printf ("paint transparency group\n"));
    11191184
    11201185  if (!mask) {
     
    11741239  cairo_pattern_destroy(mask);
    11751240
     1241  LOG(printf ("set softMask\n"));
     1242
    11761243  if (alpha == false) {
    11771244    /* We need to mask according to the luminocity of the group.
     
    12051272    groupColorSpaceStack->cs->getRGB(backdropColor, &backdropColorRGB);
    12061273    /* paint the backdrop */
    1207     cairo_set_source_rgb(maskCtx, backdropColorRGB.r / 65535.0,
    1208                          backdropColorRGB.g / 65535.0,
    1209                          backdropColorRGB.b / 65535.0);
    1210 
     1274    cairo_set_source_rgb(maskCtx,
     1275                         colToDbl(backdropColorRGB.r),
     1276                         colToDbl(backdropColorRGB.g),
     1277                         colToDbl(backdropColorRGB.b));
     1278    cairo_paint(maskCtx);
    12111279
    12121280    cairo_matrix_t mat;
     
    12161284    /* make the device offset of the new mask match that of the group */
    12171285    double x_offset, y_offset;
    1218     cairo_surface_t *pats;
    1219     cairo_pattern_get_surface(group, &pats);
    1220     cairo_surface_get_device_offset(pats, &x_offset, &y_offset);
     1286    if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) {
     1287      cairo_surface_get_device_offset(cairo_get_group_target(cairo), &x_offset, &y_offset);
     1288    } else {
     1289      cairo_surface_t *pats;
     1290      cairo_pattern_get_surface(group, &pats);
     1291      cairo_surface_get_device_offset(pats, &x_offset, &y_offset);
     1292    }
    12211293    cairo_surface_set_device_offset(source, x_offset, y_offset);
    12221294
     
    12531325    /* setup the new mask pattern */
    12541326    mask = cairo_pattern_create_for_surface(source);
    1255     cairo_matrix_t patMatrix;
    1256     cairo_pattern_get_matrix(group, &patMatrix);
    1257     cairo_pattern_set_matrix(mask, &patMatrix);
     1327
     1328    if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) {
     1329      cairo_pattern_set_matrix(mask, &mat);
     1330    } else {
     1331      cairo_matrix_t patMatrix;
     1332      cairo_pattern_get_matrix(group, &patMatrix);
     1333      cairo_pattern_set_matrix(mask, &patMatrix);
     1334    }
    12581335
    12591336    cairo_surface_destroy(source);
     
    12921369}
    12931370
     1371/* Taken from cairo/doc/tutorial/src/singular.c */
     1372static void
     1373get_singular_values (const cairo_matrix_t *matrix,
     1374                     double               *major,
     1375                     double               *minor)
     1376{
     1377        double xx = matrix->xx, xy = matrix->xy;
     1378        double yx = matrix->yx, yy = matrix->yy;
     1379
     1380        double a = xx*xx+yx*yx;
     1381        double b = xy*xy+yy*yy;
     1382        double k = xx*xy+yx*yy;
     1383
     1384        double f = (a+b) * .5;
     1385        double g = (a-b) * .5;
     1386        double delta = sqrt (g*g + k*k);
     1387
     1388        if (major)
     1389                *major = sqrt (f + delta);
     1390        if (minor)
     1391                *minor = sqrt (f - delta);
     1392}
     1393
     1394void CairoOutputDev::getScaledSize(int  orig_width,
     1395                                   int  orig_height,
     1396                                   int *scaledWidth,
     1397                                   int *scaledHeight) {
     1398  cairo_matrix_t matrix;
     1399  cairo_get_matrix(cairo, &matrix);
     1400
     1401  double xScale;
     1402  double yScale;
     1403  if (orig_width > orig_height)
     1404    get_singular_values (&matrix, &xScale, &yScale);
     1405  else
     1406    get_singular_values (&matrix, &yScale, &xScale);
     1407
     1408  int tx, tx2, ty, ty2; /* the integer co-oridinates of the resulting image */
     1409  if (xScale >= 0) {
     1410    tx = splashRound(matrix.x0 - 0.01);
     1411    tx2 = splashRound(matrix.x0 + xScale + 0.01) - 1;
     1412  } else {
     1413    tx = splashRound(matrix.x0 + 0.01) - 1;
     1414    tx2 = splashRound(matrix.x0 + xScale - 0.01);
     1415  }
     1416  *scaledWidth = abs(tx2 - tx) + 1;
     1417  //scaledWidth = splashRound(fabs(xScale));
     1418  if (*scaledWidth == 0) {
     1419    // technically, this should draw nothing, but it generally seems
     1420    // better to draw a one-pixel-wide stripe rather than throwing it
     1421    // away
     1422    *scaledWidth = 1;
     1423  }
     1424  if (yScale >= 0) {
     1425    ty = splashFloor(matrix.y0 + 0.01);
     1426    ty2 = splashCeil(matrix.y0 + yScale - 0.01);
     1427  } else {
     1428    ty = splashCeil(matrix.y0 - 0.01);
     1429    ty2 = splashFloor(matrix.y0 + yScale + 0.01);
     1430  }
     1431  *scaledHeight = abs(ty2 - ty);
     1432  if (*scaledHeight == 0) {
     1433    *scaledHeight = 1;
     1434  }
     1435}
     1436
     1437cairo_surface_t *CairoOutputDev::downscaleSurface(cairo_surface_t *orig_surface) {
     1438  cairo_surface_t *dest_surface;
     1439  unsigned char *dest_buffer;
     1440  int dest_stride;
     1441  unsigned char *orig_buffer;
     1442  int orig_width, orig_height;
     1443  int orig_stride;
     1444  int scaledHeight;
     1445  int scaledWidth;
     1446  GBool res;
     1447
     1448  if (printing)
     1449    return NULL;
     1450
     1451  orig_width = cairo_image_surface_get_width (orig_surface);
     1452  orig_height = cairo_image_surface_get_height (orig_surface);
     1453  getScaledSize (orig_width, orig_height, &scaledWidth, &scaledHeight);
     1454  if (scaledWidth >= orig_width || scaledHeight >= orig_height)
     1455    return NULL;
     1456
     1457  dest_surface = cairo_surface_create_similar (orig_surface,
     1458                                               cairo_surface_get_content (orig_surface),
     1459                                               scaledWidth, scaledHeight);
     1460  dest_buffer = cairo_image_surface_get_data (dest_surface);
     1461  dest_stride = cairo_image_surface_get_stride (dest_surface);
     1462
     1463  orig_buffer = cairo_image_surface_get_data (orig_surface);
     1464  orig_stride = cairo_image_surface_get_stride (orig_surface);
     1465
     1466  res = downscale_box_filter((uint32_t *)orig_buffer,
     1467                             orig_stride, orig_width, orig_height,
     1468                             scaledWidth, scaledHeight, 0, 0,
     1469                             scaledWidth, scaledHeight,
     1470                             (uint32_t *)dest_buffer, dest_stride);
     1471  if (!res) {
     1472    cairo_surface_destroy (dest_surface);
     1473    return NULL;
     1474  }
     1475
     1476  return dest_surface;
     1477
     1478}
     1479
     1480cairo_filter_t
     1481CairoOutputDev::getFilterForSurface(cairo_surface_t *image,
     1482                                    GBool interpolate)
     1483{
     1484  if (interpolate)
     1485    return CAIRO_FILTER_BILINEAR;
     1486
     1487  int orig_width = cairo_image_surface_get_width (image);
     1488  int orig_height = cairo_image_surface_get_height (image);
     1489  if (orig_width == 0 || orig_height == 0)
     1490          return CAIRO_FILTER_NEAREST;
     1491
     1492  int scaled_width, scaled_height;
     1493  getScaledSize (orig_width, orig_height, &scaled_width, &scaled_height);
     1494
     1495  /* When scale factor is >= 400% we don't interpolate. See bugs #25268, #9860 */
     1496  if (scaled_width / orig_width >= 4 || scaled_height / orig_height >= 4)
     1497          return CAIRO_FILTER_NEAREST;
     1498
     1499  return CAIRO_FILTER_BILINEAR;
     1500}
     1501
    12941502void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
    12951503                                   int width, int height, GBool invert,
     
    13011509  /* work around a cairo bug when scaling 1x1 surfaces */
    13021510  if (width == 1 && height == 1) {
     1511    ImageStream *imgStr;
     1512    Guchar pix;
     1513    int invert_bit;
     1514
     1515    imgStr = new ImageStream(str, width, 1, 1);
     1516    imgStr->reset();
     1517    imgStr->getPixel(&pix);
     1518    imgStr->close();
     1519    delete imgStr;
     1520
     1521    invert_bit = invert ? 1 : 0;
     1522    if (pix ^ invert_bit)
     1523      return;
     1524
    13031525    cairo_save (cairo);
    13041526    cairo_rectangle (cairo, 0., 0., width, height);
     
    13141536  }
    13151537
     1538  if (state->getFillColorSpace()->getMode() == csPattern)
     1539    cairo_push_group_with_content (cairo, CAIRO_CONTENT_ALPHA);
     1540
    13161541  /* shape is 1.0 for painted areas, 0.0 for unpainted ones */
    13171542
     
    13241549  } else {
    13251550    drawImageMaskRegular(state, ref, str, width, height, invert, interpolate, inlineImg);
     1551  }
     1552
     1553  if (state->getFillColorSpace()->getMode() == csPattern) {
     1554    if (mask)
     1555      cairo_pattern_destroy (mask);
     1556    mask = cairo_pop_group (cairo);
    13261557  }
    13271558}
     
    13401571  int invert_bit;
    13411572  int row_stride;
     1573  cairo_filter_t filter;
    13421574
    13431575  /* TODO: Do we want to cache these? */
     
    13651597    }
    13661598  }
     1599
     1600  filter = getFilterForSurface (image, interpolate);
    13671601
    13681602  cairo_surface_mark_dirty (image);
     
    13741608  LOG (printf ("drawImageMask %dx%d\n", width, height));
    13751609
    1376   /* we should actually be using CAIRO_FILTER_NEAREST here. However,
    1377    * cairo doesn't yet do minifaction filtering causing scaled down
    1378    * images with CAIRO_FILTER_NEAREST to look really bad */
    1379   cairo_pattern_set_filter (pattern,
    1380                             interpolate ? CAIRO_FILTER_BEST : CAIRO_FILTER_FAST);
    1381   cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
     1610  cairo_pattern_set_filter (pattern, filter);
     1611
     1612  if (!printing)
     1613    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
    13821614
    13831615  cairo_matrix_init_translate (&matrix, 0, height);
    13841616  cairo_matrix_scale (&matrix, width, -height);
    13851617  cairo_pattern_set_matrix (pattern, &matrix);
     1618  if (cairo_pattern_status (pattern)) {
     1619    cairo_pattern_destroy (pattern);
     1620    goto cleanup;
     1621  }
    13861622
    13871623  if (state->getFillColorSpace()->getMode() == csPattern) {
    13881624    mask = cairo_pattern_reference (pattern);
    1389   } else {
     1625  } else if (!printing) {
    13901626    cairo_save (cairo);
    13911627    cairo_rectangle (cairo, 0., 0., 1., 1.);
     
    13931629    cairo_mask (cairo, pattern);
    13941630    cairo_restore (cairo);
     1631  } else {
     1632    cairo_mask (cairo, pattern);
    13951633  }
    13961634
     
    13981636    cairo_save (cairo_shape);
    13991637    cairo_set_source (cairo_shape, pattern);
    1400     cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
    1401     cairo_fill (cairo_shape);
     1638    if (!printing) {
     1639      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
     1640      cairo_fill (cairo_shape);
     1641    } else {
     1642      cairo_mask (cairo_shape, pattern);
     1643    }
    14021644    cairo_restore (cairo_shape);
    14031645  }
     
    16451887    cairo_matrix_scale (&matrix, scaledWidth, -scaledHeight);
    16461888    cairo_pattern_set_matrix (pattern, &matrix);
     1889    if (cairo_pattern_status (pattern)) {
     1890      cairo_pattern_destroy (pattern);
     1891      imgStr->close();
     1892      delete imgStr;
     1893      return;
     1894    }
    16471895
    16481896    mask = cairo_pattern_reference (pattern);
     
    17121960  int x, y;
    17131961  int invert_bit;
     1962  cairo_filter_t filter;
     1963  cairo_filter_t maskFilter;
    17141964
    17151965  maskImgStr = new ImageStream(maskStr, maskWidth, 1, 1);
     
    17421992  delete maskImgStr;
    17431993
     1994  maskFilter = getFilterForSurface (maskImage, maskInterpolate);
     1995
    17441996  cairo_surface_mark_dirty (maskImage);
    17451997  maskPattern = cairo_pattern_create_for_surface (maskImage);
     
    17752027  }
    17762028
     2029  filter = getFilterForSurface (image, interpolate);
     2030
    17772031  cairo_surface_mark_dirty (image);
    17782032  pattern = cairo_pattern_create_for_surface (image);
     
    17832037  LOG (printf ("drawMaskedImage %dx%d\n", width, height));
    17842038
    1785   cairo_pattern_set_filter (pattern,
    1786                             interpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
    1787   cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
    1788   cairo_pattern_set_filter (maskPattern,
    1789                             maskInterpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
    1790   cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
     2039  cairo_pattern_set_filter (pattern, filter);
     2040  cairo_pattern_set_filter (maskPattern, maskFilter);
     2041
     2042  if (!printing) {
     2043    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
     2044    cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
     2045  }
    17912046
    17922047  cairo_matrix_init_translate (&matrix, 0, height);
    17932048  cairo_matrix_scale (&matrix, width, -height);
    17942049  cairo_pattern_set_matrix (pattern, &matrix);
     2050  if (cairo_pattern_status (pattern)) {
     2051    cairo_pattern_destroy (pattern);
     2052    cairo_pattern_destroy (maskPattern);
     2053    goto cleanup;
     2054  }
    17952055
    17962056  cairo_matrix_init_translate (&maskMatrix, 0, maskHeight);
    17972057  cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight);
    17982058  cairo_pattern_set_matrix (maskPattern, &maskMatrix);
    1799 
    1800   cairo_save (cairo);
    1801   cairo_set_source (cairo, pattern);
    1802   cairo_rectangle (cairo, 0., 0., 1., 1.);
    1803   cairo_clip (cairo);
    1804   cairo_mask (cairo, maskPattern);
    1805   cairo_restore (cairo);
     2059  if (cairo_pattern_status (maskPattern)) {
     2060    cairo_pattern_destroy (maskPattern);
     2061    cairo_pattern_destroy (pattern);
     2062    goto cleanup;
     2063  }
     2064
     2065  if (!printing) {
     2066    cairo_save (cairo);
     2067    cairo_set_source (cairo, pattern);
     2068    cairo_rectangle (cairo, 0., 0., 1., 1.);
     2069    cairo_clip (cairo);
     2070    cairo_mask (cairo, maskPattern);
     2071    cairo_restore (cairo);
     2072  } else {
     2073    cairo_set_source (cairo, pattern);
     2074    cairo_mask (cairo, maskPattern);
     2075  }
    18062076
    18072077  if (cairo_shape) {
    18082078    cairo_save (cairo_shape);
    18092079    cairo_set_source (cairo_shape, pattern);
    1810     cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
    1811     cairo_fill (cairo_shape);
     2080    if (!printing) {
     2081      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
     2082      cairo_fill (cairo_shape);
     2083    } else {
     2084      cairo_mask (cairo_shape, pattern);
     2085    }
    18122086    cairo_restore (cairo_shape);
    18132087  }
     
    18422116  Guchar *pix;
    18432117  int y;
     2118  cairo_filter_t filter;
     2119  cairo_filter_t maskFilter;
    18442120
    18452121  maskImgStr = new ImageStream(maskStr, maskWidth,
     
    18652141  maskImgStr->close();
    18662142  delete maskImgStr;
     2143
     2144  maskFilter = getFilterForSurface (maskImage, maskInterpolate);
    18672145
    18682146  cairo_surface_mark_dirty (maskImage);
     
    18992177  }
    19002178
     2179  filter = getFilterForSurface (image, interpolate);
     2180
    19012181  cairo_surface_mark_dirty (image);
    19022182  pattern = cairo_pattern_create_for_surface (image);
     
    19072187  LOG (printf ("drawSoftMaskedImage %dx%d\n", width, height));
    19082188
    1909   //XXX: should set mask filter
    1910   cairo_pattern_set_filter (pattern,
    1911                             interpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
    1912   cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
    1913   cairo_pattern_set_filter (maskPattern,
    1914                             maskInterpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
    1915   cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
     2189  cairo_pattern_set_filter (pattern, filter);
     2190  cairo_pattern_set_filter (maskPattern, maskFilter);
     2191
     2192  if (!printing) {
     2193    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
     2194    cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
     2195  }
    19162196
    19172197  cairo_matrix_init_translate (&matrix, 0, height);
    19182198  cairo_matrix_scale (&matrix, width, -height);
    19192199  cairo_pattern_set_matrix (pattern, &matrix);
     2200  if (cairo_pattern_status (pattern)) {
     2201    cairo_pattern_destroy (pattern);
     2202    cairo_pattern_destroy (maskPattern);
     2203    goto cleanup;
     2204  }
    19202205
    19212206  cairo_matrix_init_translate (&maskMatrix, 0, maskHeight);
    19222207  cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight);
    19232208  cairo_pattern_set_matrix (maskPattern, &maskMatrix);
    1924 
    1925   cairo_save (cairo);
     2209  if (cairo_pattern_status (maskPattern)) {
     2210    cairo_pattern_destroy (maskPattern);
     2211    cairo_pattern_destroy (pattern);
     2212    goto cleanup;
     2213  }
     2214
     2215  if (fill_opacity != 1.0)
     2216    cairo_push_group (cairo);
     2217  else
     2218    cairo_save (cairo);
     2219
    19262220  cairo_set_source (cairo, pattern);
    1927   cairo_rectangle (cairo, 0., 0.,
    1928                    MIN (width, maskWidth) / (double)width,
    1929                    MIN (height, maskHeight) / (double)height);
    1930   cairo_clip (cairo);
     2221  if (!printing) {
     2222    cairo_rectangle (cairo, 0., 0.,
     2223                     MIN (width, maskWidth) / (double)width,
     2224                     MIN (height, maskHeight) / (double)height);
     2225    cairo_clip (cairo);
     2226  }
    19312227  cairo_mask (cairo, maskPattern);
     2228
     2229  if (fill_opacity != 1.0) {
     2230    cairo_pop_group_to_source (cairo);
     2231    cairo_save (cairo);
     2232    if (!printing) {
     2233      cairo_rectangle (cairo, 0., 0.,
     2234                       MIN (width, maskWidth) / (double)width,
     2235                       MIN (height, maskHeight) / (double)height);
     2236      cairo_clip (cairo);
     2237    }
     2238    cairo_paint_with_alpha (cairo, fill_opacity);
     2239  }
    19322240  cairo_restore (cairo);
    19332241
     
    19352243    cairo_save (cairo_shape);
    19362244    cairo_set_source (cairo_shape, pattern);
    1937     cairo_rectangle (cairo_shape, 0., 0.,
    1938                      MIN (width, maskWidth) / (double)width,
    1939                      MIN (height, maskHeight) / (double)height);
    1940     cairo_fill (cairo_shape);
     2245    if (!printing) {
     2246      cairo_rectangle (cairo_shape, 0., 0.,
     2247                       MIN (width, maskWidth) / (double)width,
     2248                       MIN (height, maskHeight) / (double)height);
     2249      cairo_fill (cairo_shape);
     2250    } else {
     2251      cairo_mask (cairo_shape, pattern);
     2252    }
    19412253    cairo_restore (cairo_shape);
    19422254  }
     
    19482260  imgStr->close();
    19492261  delete imgStr;
     2262}
     2263
     2264GBool CairoOutputDev::getStreamData (Stream *str, char **buffer, int *length)
     2265{
     2266  int len, i;
     2267  char *strBuffer;
     2268
     2269  len = 0;
     2270  str->close();
     2271  str->reset();
     2272  while (str->getChar() != EOF) len++;
     2273  if (len == 0)
     2274    return gFalse;
     2275
     2276  strBuffer = (char *)gmalloc (len);
     2277
     2278  str->close();
     2279  str->reset();
     2280  for (i = 0; i < len; ++i)
     2281    strBuffer[i] = str->getChar();
     2282
     2283  *buffer = strBuffer;
     2284  *length = len;
     2285
     2286  return gTrue;
    19502287}
    19512288
     
    19632300  int stride, i;
    19642301  GfxRGB *lookup = NULL;
     2302  cairo_filter_t filter = CAIRO_FILTER_BILINEAR;
    19652303
    19662304  /* TODO: Do we want to cache these? */
     
    20442382  gfree(lookup);
    20452383
     2384  LOG (printf ("drawImage %dx%d\n", width, height));
     2385
     2386  cairo_surface_t *scaled_surface;
     2387
     2388  scaled_surface = downscaleSurface (image);
     2389  if (scaled_surface) {
     2390    if (cairo_surface_status (scaled_surface))
     2391      goto cleanup;
     2392    cairo_surface_destroy (image);
     2393    image = scaled_surface;
     2394    width = cairo_image_surface_get_width (image);
     2395    height = cairo_image_surface_get_height (image);
     2396  } else {
     2397    filter = getFilterForSurface (image, interpolate);
     2398  }
     2399
    20462400  cairo_surface_mark_dirty (image);
     2401
     2402#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 6)
     2403  if (printing && (str->getKind() == strDCT || str->getKind() == strJPX)) {
     2404    char *strBuffer;
     2405    int len;
     2406
     2407    if (getStreamData (str->getNextStream(), &strBuffer, &len)) {
     2408      cairo_status_t st;
     2409      st = cairo_surface_set_mime_data (image,
     2410                                        str->getKind() == strDCT ?
     2411                                        CAIRO_MIME_TYPE_JPEG : CAIRO_MIME_TYPE_JP2,
     2412                                        (const unsigned char *)strBuffer, len,
     2413                                        gfree, strBuffer);
     2414      if (st)
     2415        gfree (strBuffer);
     2416    }
     2417  }
     2418#endif /* CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 6) */
     2419
    20472420  pattern = cairo_pattern_create_for_surface (image);
    20482421  cairo_surface_destroy (image);
     
    20502423    goto cleanup;
    20512424
    2052   LOG (printf ("drawImage %dx%d\n", width, height));
    2053 
    2054   cairo_pattern_set_filter (pattern,
    2055                             interpolate ?
    2056                             CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
    2057   cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
     2425  cairo_pattern_set_filter (pattern, filter);
     2426
     2427  if (!printing)
     2428    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
    20582429
    20592430  cairo_matrix_init_translate (&matrix, 0, height);
    20602431  cairo_matrix_scale (&matrix, width, -height);
    20612432  cairo_pattern_set_matrix (pattern, &matrix);
     2433  if (cairo_pattern_status (pattern)) {
     2434    cairo_pattern_destroy (pattern);
     2435    goto cleanup;
     2436  }
    20622437
    20632438  if (!mask && fill_opacity != 1.0) {
     
    20712446  cairo_save (cairo);
    20722447  cairo_set_source (cairo, pattern);
    2073   cairo_rectangle (cairo, 0., 0., 1., 1.);
     2448  if (printing)
     2449    cairo_rectangle (cairo, 0., 0., width, height);
     2450  else
     2451    cairo_rectangle (cairo, 0., 0., 1., 1.);
    20742452  if (maskPattern) {
    20752453    cairo_clip (cairo);
     
    20852463    cairo_save (cairo_shape);
    20862464    cairo_set_source (cairo_shape, pattern);
    2087     cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
     2465    if (printing)
     2466      cairo_rectangle (cairo_shape, 0., 0., width, height);
     2467    else
     2468      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
    20882469    cairo_fill (cairo_shape);
    20892470    cairo_restore (cairo_shape);
Note: See TracChangeset for help on using the changeset viewer.