Beispiel #1
0
FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT*         rect,
        FX_ARGB                   fillArgb,
        int                       alphaFlag	   ,
        void*                     iccTransform ,
        int						blend_type )
{
    CGBlendMode mode = GetCGBlendMode(blend_type);
    if (mode != kCGBlendModeNormal) {
        CGContextSetBlendMode(_context, mode);
    }
    CGRect rect_fx = CGRectMake(rect->left, rect->top, rect->Width(), rect->Height());
    CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
    FX_INT32 a, r, g, b;
    ArgbDecode(fillArgb, a, r, g, b);
    CGContextSetRGBFillColor(_context,
                             r / 255.f,
                             g / 255.f,
                             b / 255.f,
                             a / 255.f);
    CGContextFillRect(_context, rect_usr);
    if (mode != kCGBlendModeNormal) {
        CGContextSetBlendMode(_context, kCGBlendModeNormal);
    }
    return TRUE;
}
Beispiel #2
0
FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect)
{
    CGRect r = CGContextGetClipBoundingBox(_context);
    r = CGRectApplyAffineTransform(r, _user2FoxitDevice);
    rect->left		= FXSYS_floor(r.origin.x);
    rect->top		= FXSYS_floor(r.origin.y);
    rect->right		= FXSYS_ceil(r.origin.x + r.size.width);
    rect->bottom	= FXSYS_ceil(r.origin.y + r.size.height);
    return TRUE;
}
Beispiel #3
0
void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height,
        CGRect* rect )
{
    int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1;
    int flip_x = _foxitDevice2User.a * dest_width > 0 ? 1 : -1;
    if (flip_y < 0 || flip_x < 0) {
        if (dest_height < 0) {
            dest_height = -dest_height;
            dest_top -= dest_height;
        }
        CGRect rt = CGRectApplyAffineTransform(CGRectMake(dest_left, dest_top, dest_width, dest_height), _foxitDevice2User);
        CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f,
                offset_y = (rt.origin.y) + rt.size.height / 2.f;
        CGAffineTransform transform = CGAffineTransformIdentity;
        transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y));
        transform = CGAffineTransformConcat(transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0));
        transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y));
        CGContextConcatCTM(_context, transform);
        if (rect) {
            *rect = CGRectApplyAffineTransform(*rect, transform);
        }
    }
}
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription description)
{
#if PLATFORM(IOS)
    startAnimation(DoNotCatchUp);
#else
    startAnimation();
#endif

    RetainPtr<CGImageRef> image;
    // Never use subsampled images for drawing into PDF contexts.
    if (wkCGContextIsPDFContext(ctxt->platformContext()))
        image = adoptCF(copyUnscaledFrameAtIndex(m_currentFrame));
    else {
        CGRect transformedDestinationRect = CGRectApplyAffineTransform(destRect, CGContextGetCTM(ctxt->platformContext()));
        float subsamplingScale = std::min<float>(1, std::max(transformedDestinationRect.size.width / srcRect.width(), transformedDestinationRect.size.height / srcRect.height()));

        image = frameAtIndex(m_currentFrame, subsamplingScale);
    }

    if (!image) // If it's too early we won't have an image yet.
        return;
    
    if (mayFillWithSolidColor()) {
        fillWithSolidColor(ctxt, destRect, solidColor(), styleColorSpace, compositeOp);
        return;
    }

    // Subsampling may have given us an image that is smaller than size().
    IntSize imageSize(CGImageGetWidth(image.get()), CGImageGetHeight(image.get()));
    
    // srcRect is in the coordinates of the unsubsampled image, so we have to map it to the subsampled image.
    FloatRect scaledSrcRect = srcRect;
    if (imageSize != m_size) {
        FloatRect originalImageBounds(FloatPoint(), m_size);
        FloatRect subsampledImageBounds(FloatPoint(), imageSize);
        scaledSrcRect = mapRect(srcRect, originalImageBounds, subsampledImageBounds);
    }
    
    ImageOrientation orientation;
    if (description.respectImageOrientation() == RespectImageOrientation)
        orientation = frameOrientationAtIndex(m_currentFrame);

    ctxt->drawNativeImage(image.get(), imageSize, styleColorSpace, destRect, scaledSrcRect, compositeOp, blendMode, orientation);

    if (imageObserver())
        imageObserver()->didDraw(this);
}
Beispiel #5
0
static void quartzgen_begin_anchor(GVJ_t *job, char *url, char *tooltip, char *target, char *id)
{
    pointf *url_map = job->obj->url_map_p;
	if (url && url_map) {
		/* set up the hyperlink to the given url */
		CGContextRef context = (CGContextRef)job->context;
		CFURLRef uri = CFURLCreateWithBytes (kCFAllocatorDefault, (const UInt8 *)url, strlen(url), kCFStringEncodingUTF8, NULL);
		CGPDFContextSetURLForRect(
			context,
			uri,
			/* need to reverse the CTM on the area to get it to work */
			CGRectApplyAffineTransform(CGRectMake(url_map[0].x, url_map[0].y, url_map[1].x - url_map[0].x, url_map[1].y - url_map[0].y),CGContextGetCTM(context))
		);

		/* clean up */
		CFRelease(uri);
	}
}
Beispiel #6
0
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription description)
{
    CGImageRef image;
#if !PLATFORM(IOS)
    startAnimation();

    image = frameAtIndex(m_currentFrame);
#else
    startAnimation(DoNotCatchUp);

    CGRect transformedDestinationRect = CGRectApplyAffineTransform(destRect, CGContextGetCTM(ctxt->platformContext()));
    RetainPtr<CGImageRef> imagePossiblyCopied;
    // Never use subsampled images for drawing into PDF contexts.
    if (CGContextGetType(ctxt->platformContext()) == kCGContextTypePDF)
        imagePossiblyCopied = adoptCF(copyUnscaledFrameAtIndex(m_currentFrame));
    else
        imagePossiblyCopied = frameAtIndex(m_currentFrame, std::min<float>(1.0f, std::max(transformedDestinationRect.size.width  / srcRect.width(), transformedDestinationRect.size.height / srcRect.height())));

    image = imagePossiblyCopied.get();
#endif
    if (!image) // If it's too early we won't have an image yet.
        return;

    if (mayFillWithSolidColor()) {
        fillWithSolidColor(ctxt, destRect, solidColor(), styleColorSpace, compositeOp);
        return;
    }

    float scale = 1;
#if PLATFORM(IOS)
    scale = m_frames[m_currentFrame].m_scale;
#endif
    FloatSize selfSize = currentFrameSize();
    ImageOrientation orientation;

    if (description.respectImageOrientation() == RespectImageOrientation)
        orientation = frameOrientationAtIndex(m_currentFrame);

    ctxt->drawNativeImage(image, selfSize, styleColorSpace, destRect, srcRect, scale, compositeOp, blendMode, orientation);

    if (imageObserver())
        imageObserver()->didDraw(this);
}
Beispiel #7
0
void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
{
    if (paintingDisabled())
        return;

    RetainPtr<CFURLRef> urlRef(AdoptCF, link.createCFURL());
    if (!urlRef)
        return;

    CGContextRef context = platformContext();

    // Get the bounding box to handle clipping.
    CGRect box = CGContextGetClipBoundingBox(context);

    IntRect intBox((int)box.origin.x, (int)box.origin.y, (int)box.size.width, (int)box.size.height);
    IntRect rect = destRect;
    rect.intersect(intBox);

    CGPDFContextSetURLForRect(context, urlRef.get(),
        CGRectApplyAffineTransform(rect, CGContextGetCTM(context)));
}
Beispiel #8
0
FloatRect AffineTransform::mapRect(const FloatRect &rect) const
{
    return FloatRect(CGRectApplyAffineTransform(CGRect(rect), m_transform));
}
Beispiel #9
0
IntRect AffineTransform::mapRect(const IntRect &rect) const
{
    return enclosingIntRect(CGRectApplyAffineTransform(CGRect(rect), m_transform));
}
static cairo_int_status_t
_cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
				  cairo_scaled_glyph_t *scaled_glyph)
{
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;

    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);

    cairo_image_surface_t *surface = NULL;

    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);

    int advance;
    CGRect bbox;
    double width, height;
    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);

    CGContextRef cgContext = NULL;
    CGAffineTransform textMatrix;
    CGRect glyphRect, glyphRectInt;
    CGPoint glyphOrigin;

    //fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface);

    /* Create blank 2x2 image if we don't have this character.
     * Maybe we should draw a better missing-glyph slug or something,
     * but this is ok for now.
     */
    if (glyph == INVALID_GLYPH) {
	surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
	status = cairo_surface_status ((cairo_surface_t *) surface);
	if (status)
	    return status;

	_cairo_scaled_glyph_set_surface (scaled_glyph,
					 &font->base,
					 surface);
	return CAIRO_STATUS_SUCCESS;
    }

    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
    {
	return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    /* scale(1,-1) * font->base.scale * scale(1,-1) */
    textMatrix = CGAffineTransformMake (font->base.scale.xx,
					-font->base.scale.yx,
					-font->base.scale.xy,
					font->base.scale.yy,
					0, -0);
    glyphRect = CGRectMake (bbox.origin.x / emscale,
			    bbox.origin.y / emscale,
			    bbox.size.width / emscale,
			    bbox.size.height / emscale);

    glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix);

    /* Round the rectangle outwards, so that we don't have to deal
     * with non-integer-pixel origins or dimensions.
     */
    glyphRectInt = CGRectIntegral (glyphRect);

#if 0
    fprintf (stderr, "glyphRect[o]: %f %f %f %f\n",
	     glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
    fprintf (stderr, "glyphRectInt: %f %f %f %f\n",
	     glyphRectInt.origin.x, glyphRectInt.origin.y, glyphRectInt.size.width, glyphRectInt.size.height);
#endif

    glyphOrigin = glyphRectInt.origin;

    //textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm));

    width = glyphRectInt.size.width;
    height = glyphRectInt.size.height;

    //fprintf (stderr, "glyphRect[n]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);

    surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
    if (surface->base.status)
	return surface->base.status;

    if (surface->width != 0 && surface->height != 0) {
	cgContext = CGBitmapContextCreate (surface->data,
					   surface->width,
					   surface->height,
					   8,
					   surface->stride,
					   NULL,
					   kCGImageAlphaOnly);

	if (cgContext == NULL) {
	    cairo_surface_destroy (&surface->base);
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
	}

	CGContextSetFont (cgContext, font_face->cgFont);
	CGContextSetFontSize (cgContext, 1.0);
	CGContextSetTextMatrix (cgContext, textMatrix);

	switch (font->base.options.antialias) {
	case CAIRO_ANTIALIAS_SUBPIXEL:
	case CAIRO_ANTIALIAS_BEST:
	    CGContextSetShouldAntialias (cgContext, TRUE);
	    CGContextSetShouldSmoothFonts (cgContext, TRUE);
	    if (CGContextSetAllowsFontSmoothingPtr &&
		!CGContextGetAllowsFontSmoothingPtr (cgContext))
		CGContextSetAllowsFontSmoothingPtr (cgContext, TRUE);
	    break;
	case CAIRO_ANTIALIAS_NONE:
	    CGContextSetShouldAntialias (cgContext, FALSE);
	    break;
	case CAIRO_ANTIALIAS_GRAY:
	case CAIRO_ANTIALIAS_GOOD:
	case CAIRO_ANTIALIAS_FAST:
	    CGContextSetShouldAntialias (cgContext, TRUE);
	    CGContextSetShouldSmoothFonts (cgContext, FALSE);
	    break;
	case CAIRO_ANTIALIAS_DEFAULT:
	default:
	    /* Don't do anything */
	    break;
	}

	CGContextSetAlpha (cgContext, 1.0);
	CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1);

	CGContextRelease (cgContext);
    }

    cairo_surface_set_device_offset (&surface->base,
				     - glyphOrigin.x,
				     height + glyphOrigin.y);

    _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface);

    return status;
}
static cairo_int_status_t
_cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
				  cairo_scaled_glyph_t *scaled_glyph)
{
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;

    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
    cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
    int advance;
    CGRect bbox;
    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
    double xmin, ymin, xmax, ymax;

    if (glyph == INVALID_GLYPH)
	goto FAIL;

    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
	goto FAIL;

    /* broken fonts like Al Bayan return incorrect bounds for some null characters,
       see https://bugzilla.mozilla.org/show_bug.cgi?id=534260 */
    if (unlikely (bbox.origin.x == -32767 &&
                  bbox.origin.y == -32767 &&
                  bbox.size.width == 65534 &&
                  bbox.size.height == 65534)) {
        bbox.origin.x = bbox.origin.y = 0;
        bbox.size.width = bbox.size.height = 0;
    }

    bbox = CGRectMake (bbox.origin.x / emscale,
		       bbox.origin.y / emscale,
		       bbox.size.width / emscale,
		       bbox.size.height / emscale);

    /* Should we want to always integer-align glyph extents, we can do so in this way */
#if 0
    {
	CGAffineTransform textMatrix;
	textMatrix = CGAffineTransformMake (font->base.scale.xx,
					    -font->base.scale.yx,
					    -font->base.scale.xy,
					    font->base.scale.yy,
					    0.0f, 0.0f);

	bbox = CGRectApplyAffineTransform (bbox, textMatrix);
	bbox = CGRectIntegral (bbox);
	bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix));
    }
#endif

#if 0
    fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph,
	     bbox.origin.x / emscale, bbox.origin.y / emscale,
	     bbox.size.width / emscale, bbox.size.height / emscale);
#endif

    xmin = CGRectGetMinX(bbox);
    ymin = CGRectGetMinY(bbox);
    xmax = CGRectGetMaxX(bbox);
    ymax = CGRectGetMaxY(bbox);

    extents.x_bearing = xmin;
    extents.y_bearing = - ymax;
    extents.width = xmax - xmin;
    extents.height = ymax - ymin;

    extents.x_advance = (double) advance / emscale;
    extents.y_advance = 0.0;

#if 0
    fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph,
	     extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance);
#endif

  FAIL:
    _cairo_scaled_glyph_set_metrics (scaled_glyph,
				     &font->base,
				     &extents);

    return status;
}
static cairo_int_status_t
_cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
				  cairo_scaled_glyph_t *scaled_glyph)
{
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;

    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);

    cairo_image_surface_t *surface = NULL;

    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);

    int advance;
    CGRect bbox;
    double width, height;
    double xscale, yscale;
    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);

    CGColorSpaceRef gray;
    CGContextRef cgContext = NULL;
    CGAffineTransform textMatrix;
    CGRect glyphRect, glyphRectInt;
    CGPoint glyphOrigin;

    //fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface);

    /* Create blank 2x2 image if we don't have this character.
     * Maybe we should draw a better missing-glyph slug or something,
     * but this is ok for now.
     */
    if (glyph == INVALID_GLYPH) {
	surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
	status = cairo_surface_status ((cairo_surface_t *) surface);
	if (status)
	    return status;

	_cairo_scaled_glyph_set_surface (scaled_glyph,
					 &font->base,
					 surface);
	return CAIRO_STATUS_SUCCESS;
    }

    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
    {
	return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    status = _cairo_matrix_compute_basis_scale_factors (&font->base.scale,
						  &xscale, &yscale, 1);
    if (status)
	return status;

    textMatrix = CGAffineTransformMake (font->base.scale.xx,
					-font->base.scale.yx,
					-font->base.scale.xy,
					font->base.scale.yy,
					0.0f, 0.0f);
    glyphRect = CGRectMake (bbox.origin.x / emscale,
			    bbox.origin.y / emscale,
			    bbox.size.width / emscale,
			    bbox.size.height / emscale);

    glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix);

    /* Round the rectangle outwards, so that we don't have to deal
     * with non-integer-pixel origins or dimensions.
     */
    glyphRectInt = CGRectIntegral (glyphRect);

#if 0
    fprintf (stderr, "glyphRect[o]: %f %f %f %f\n",
	     glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
    fprintf (stderr, "glyphRectInt: %f %f %f %f\n",
	     glyphRectInt.origin.x, glyphRectInt.origin.y, glyphRectInt.size.width, glyphRectInt.size.height);
#endif

    glyphOrigin = glyphRectInt.origin;

    //textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm));

    width = glyphRectInt.size.width;
    height = glyphRectInt.size.height;

    //fprintf (stderr, "glyphRect[n]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);

    surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
    if (surface->base.status)
	return surface->base.status;

    gray = CGColorSpaceCreateDeviceGray ();
    cgContext = CGBitmapContextCreate (surface->data,
				       surface->width,
				       surface->height,
				       8,
				       surface->stride,
				       gray,
				       kCGImageAlphaNone);
    CGColorSpaceRelease (gray);

    CGContextSetFont (cgContext, font_face->cgFont);
    CGContextSetFontSize (cgContext, 1.0);
    CGContextSetTextMatrix (cgContext, textMatrix);

    CGContextClearRect (cgContext, CGRectMake (0.0f, 0.0f, width, height));

    if (font->base.options.antialias == CAIRO_ANTIALIAS_NONE)
	CGContextSetShouldAntialias (cgContext, false);

    CGContextSetRGBFillColor (cgContext, 1.0, 1.0, 1.0, 1.0);
    CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1);

    CGContextRelease (cgContext);

    cairo_surface_set_device_offset (&surface->base,
				     - glyphOrigin.x,
				     height + glyphOrigin.y);

    _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface);

    return status;
}
static cairo_int_status_t
_cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
				  cairo_scaled_glyph_t *scaled_glyph)
{
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;

    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
    cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
    CGAffineTransform textMatrix;
    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
    int advance;
    CGRect bbox;
    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
    double xscale, yscale;
    double xmin, ymin, xmax, ymax;

    if (glyph == INVALID_GLYPH)
	goto FAIL;

    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
	goto FAIL;

    status = _cairo_matrix_compute_basis_scale_factors (&font->base.scale,
						  &xscale, &yscale, 1);
    if (status)
	goto FAIL;

    bbox = CGRectMake (bbox.origin.x / emscale,
		       bbox.origin.y / emscale,
		       bbox.size.width / emscale,
		       bbox.size.height / emscale);

    /* Should we want to always integer-align glyph extents, we can do so in this way */
#if 0
    {
	CGAffineTransform textMatrix;
	textMatrix = CGAffineTransformMake (font->base.scale.xx,
					    -font->base.scale.yx,
					    -font->base.scale.xy,
					    font->base.scale.yy,
					    0.0f, 0.0f);

	bbox = CGRectApplyAffineTransform (bbox, textMatrix);
	bbox = CGRectIntegral (bbox);
	bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix));
    }
#endif

#if 0
    fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph,
	     bbox.origin.x / emscale, bbox.origin.y / emscale,
	     bbox.size.width / emscale, bbox.size.height / emscale);
#endif

    xmin = CGRectGetMinX(bbox);
    ymin = CGRectGetMinY(bbox);
    xmax = CGRectGetMaxX(bbox);
    ymax = CGRectGetMaxY(bbox);

    extents.x_bearing = xmin;
    extents.y_bearing = - ymax;
    extents.width = xmax - xmin;
    extents.height = ymax - ymin;

    extents.x_advance = (double) advance / emscale;
    extents.y_advance = 0.0;

#if 0
    fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph,
	     extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance);
#endif

  FAIL:
    _cairo_scaled_glyph_set_metrics (scaled_glyph,
				     &font->base,
				     &extents);

    return status;
}
Beispiel #14
0
FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource*      pBitmap,
        FX_ARGB                     argb,
        int                         dest_left,
        int                         dest_top,
        int                         dest_width,
        int                         dest_height,
        const FX_RECT*              clipRect,
        FX_DWORD                    flags,
        int                         alphaFlag	   ,
        void*                       iccTransform ,
        int							blend_type)
{
    SaveState();
    if (clipRect) {
        CGContextBeginPath(_context);
        CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, clipRect->Width(), clipRect->Height());
        rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User);
        CGContextAddRect(_context, rect_clip);
        CGContextClip(_context);
    }
    CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height);
    rect = CGRectApplyAffineTransform(rect, _foxitDevice2User);
    if (FXDIB_BICUBIC_INTERPOL == flags) {
        CGContextSetInterpolationQuality(_context, kCGInterpolationHigh);
    } else if (FXDIB_DOWNSAMPLE == flags) {
        CGContextSetInterpolationQuality(_context, kCGInterpolationNone);
    } else {
        CGContextSetInterpolationQuality(_context, kCGInterpolationMedium);
    }
    CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height);
    CFX_DIBitmap* pBitmap1 = NULL;
    if (pBitmap->IsAlphaMask()) {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
        if (NULL == pBitmap1) {
            RestoreState(FALSE);
            return FALSE;
        }
        CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
                                            pBitmap1->GetBuffer(),
                                            pBitmap1->GetPitch() * pBitmap1->GetHeight(),
                                            NULL);
        CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
        CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
        CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
                                          pBitmap1->GetHeight(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetPitch(),
                                          pColorSpace,
                                          bitmapInfo,
                                          pBitmapProvider, NULL, true,
                                          kCGRenderingIntentDefault);
        CGContextClipToMask(_context, rect, pImage);
        CGContextSetRGBFillColor(_context,
                                 FXARGB_R(argb) / 255.f,
                                 FXARGB_G(argb) / 255.f,
                                 FXARGB_B(argb) / 255.f,
                                 FXARGB_A(argb) / 255.f);
        CGContextFillRect(_context, rect);
        CGImageRelease(pImage);
        CGColorSpaceRelease(pColorSpace);
        CGDataProviderRelease(pBitmapProvider);
        if (pBitmap1 != pBitmap) {
            delete pBitmap1;
        }
        RestoreState(FALSE);
        return TRUE;
    }
    if (pBitmap->GetBPP() < 32) {
        pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
    } else {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
    }
    if (NULL == pBitmap1) {
        RestoreState(FALSE);
        return FALSE;
    }
    if (pBitmap1->HasAlpha()) {
        if (pBitmap1 == pBitmap) {
            pBitmap1 = pBitmap->Clone();
            if (!pBitmap1) {
                RestoreState(FALSE);
                return FALSE;
            }
        }
        for (int row = 0; row < pBitmap1->GetHeight(); row ++) {
            FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
            for (int col = 0; col < pBitmap1->GetWidth(); col ++) {
                pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
                pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
                pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
                pScanline += 4;
            }
        }
    }
    CGContextRef ctx = createContextWithBitmap(pBitmap1);
    CGImageRef image = CGBitmapContextCreateImage(ctx);
    CGContextDrawImage(_context, rect, image);
    CGImageRelease(image);
    CGContextRelease(ctx);
    if (pBitmap1 != pBitmap) {
        delete pBitmap1;
    }
    RestoreState(FALSE);
    return TRUE;
}
Beispiel #15
0
FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource*      pBitmap,
        FX_ARGB                     argb,
        const FX_RECT*              srcRect,
        int                         dest_left,
        int                         dest_top,
        int                         blendType,
        int                         alphaFlag       ,
        void*                       iccTransform    )
{
    SaveState();
    CGFloat src_left, src_top, src_width, src_height;
    if (srcRect) {
        src_left = srcRect->left;
        src_top = srcRect->top;
        src_width = srcRect->Width();
        src_height = srcRect->Height();
    } else {
        src_left = src_top = 0;
        src_width = pBitmap->GetWidth();
        src_height = pBitmap->GetHeight();
    }
    CGAffineTransform ctm = CGContextGetCTM(_context);
    CGFloat scale_x = FXSYS_fabs(ctm.a);
    CGFloat scale_y = FXSYS_fabs(ctm.d);
    src_left /= scale_x;
    src_top /= scale_y;
    src_width /= scale_x;
    src_height /= scale_y;
    CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height);
    CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
    CGContextBeginPath(_context);
    CGContextAddRect(_context, rect_usr);
    CGContextClip(_context);
    rect_usr.size = CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y);
    rect_usr = CGRectOffset(rect_usr, -src_left, -src_top);
    CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr);
    CFX_DIBitmap* pBitmap1 = NULL;
    if (pBitmap->IsAlphaMask()) {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
        if (NULL == pBitmap1) {
            RestoreState(FALSE);
            return FALSE;
        }
        CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
                                            pBitmap1->GetBuffer(),
                                            pBitmap1->GetPitch() * pBitmap1->GetHeight(),
                                            NULL);
        CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
        CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
        CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
                                          pBitmap1->GetHeight(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetBPP(),
                                          pBitmap1->GetPitch(),
                                          pColorSpace,
                                          bitmapInfo,
                                          pBitmapProvider, NULL, true,
                                          kCGRenderingIntentDefault);
        CGContextClipToMask(_context, rect_usr, pImage);
        CGContextSetRGBFillColor(_context,
                                 FXARGB_R(argb) / 255.f,
                                 FXARGB_G(argb) / 255.f,
                                 FXARGB_B(argb) / 255.f,
                                 FXARGB_A(argb) / 255.f);
        CGContextFillRect(_context, rect_usr);
        CGImageRelease(pImage);
        CGColorSpaceRelease(pColorSpace);
        CGDataProviderRelease(pBitmapProvider);
        if (pBitmap1 != pBitmap) {
            delete pBitmap1;
        }
        RestoreState(FALSE);
        return TRUE;
    }
    if (pBitmap->GetBPP() < 32) {
        pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
    } else {
        if (pBitmap->GetBuffer()) {
            pBitmap1 = (CFX_DIBitmap*)pBitmap;
        } else {
            pBitmap1 = pBitmap->Clone();
        }
    }
    if (NULL == pBitmap1) {
        RestoreState(FALSE);
        return FALSE;
    }
    if (pBitmap1->HasAlpha()) {
        if (pBitmap1 == pBitmap) {
            pBitmap1 = pBitmap->Clone();
            if (!pBitmap1) {
                RestoreState(FALSE);
                return FALSE;
            }
        }
        for (int row = 0; row < pBitmap1->GetHeight(); row ++) {
            FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
            for (int col = 0; col < pBitmap1->GetWidth(); col ++) {
                pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
                pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
                pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
                pScanline += 4;
            }
        }
    }
    CGContextRef ctx = createContextWithBitmap(pBitmap1);
    CGImageRef image = CGBitmapContextCreateImage(ctx);
    int blend_mode = blendType;
    if (FXDIB_BLEND_HARDLIGHT == blendType) {
        blend_mode = kCGBlendModeSoftLight;
    } else if (FXDIB_BLEND_SOFTLIGHT == blendType) {
        blend_mode = kCGBlendModeHardLight;
    } else if (blendType >= FXDIB_BLEND_NONSEPARABLE && blendType <= FXDIB_BLEND_LUMINOSITY) {
        blend_mode = blendType - 9;
    } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) {
        blend_mode = kCGBlendModeNormal;
    }
    CGContextSetBlendMode(_context, (CGBlendMode)blend_mode);
    CGContextDrawImage(_context, rect_usr, image);
    CGImageRelease(image);
    CGContextRelease(ctx);
    if (pBitmap1 != pBitmap) {
        delete pBitmap1;
    }
    RestoreState(FALSE);
    return TRUE;
}