void MacDock::overlay(const QString& text) { if (text.isEmpty()) { overlayed = false; RestoreApplicationDockTileImage(); return; } // Create the context CGContextRef context = BeginCGContextForApplicationDockTile(); if (!overlayed) { overlayed = true; // Add some subtle drop down shadow // FIXME: Disabled because 10.2 doesn't support it //CGSize s = { 2.0, -4.0 }; //CGContextSetShadow(context,s,5.0); } // Draw a circle CGContextBeginPath(context); CGContextAddArc(context, 95.0, 95.0, 25.0, 0.0, 2 * M_PI, true); CGContextClosePath(context); CGContextSetRGBFillColor(context, 1, 0.0, 0.0, 1); CGContextFillPath(context); // Set the clipping path to the same circle CGContextBeginPath(context); CGContextAddArc(context, 95.0, 95.0, 25.0, 0.0, 2 * M_PI, true); CGContextClip(context); // Remove drop shadow // FIXME: Disabled because 10.2 doesn't support it //CGSize s = { 0.0, -0.0 }; //CGContextSetShadowWithColor(context, s, 0, NULL); // Select the appropriate font CGContextSelectFont(context,DOCK_FONT_NAME, DOCK_FONT_SIZE, kCGEncodingMacRoman); CGContextSetRGBFillColor(context, 1, 1, 1, 1); // Draw the text invisible CGPoint begin = CGContextGetTextPosition(context); CGContextSetTextDrawingMode(context, kCGTextInvisible); CGContextShowTextAtPoint(context, begin.x, begin.y, text.toStdString().c_str(), text.length()); CGPoint end = CGContextGetTextPosition(context); // Draw the text CGContextSetTextDrawingMode(context, kCGTextFill); CGContextShowTextAtPoint(context, 95 - (end.x - begin.x)/2, 95 - 8, text.toStdString().c_str(), text.length()); // Cleanup CGContextFlush(context); EndCGContextForApplicationDockTile(context); }
static double Quartz_StrWidth(char *str, R_GE_gcontext *gc, NewDevDesc *dd) { QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific; CGPoint position; CGContextSaveGState( GetContext(xd) ); CGContextTranslateCTM( GetContext(xd), 0, 0 ); CGContextScaleCTM( GetContext(xd), -1, 1); CGContextRotateCTM( GetContext(xd), -1.0 * 3.1416); CGContextSetTextDrawingMode( GetContext(xd), kCGTextInvisible ); Quartz_SetFont(gc->fontfamily, gc->fontface, gc->cex, gc->ps, dd); CGContextShowTextAtPoint( GetContext(xd), 0, 0, str, strlen(str) ); position = CGContextGetTextPosition( GetContext(xd) ); CGContextRestoreGState( GetContext(xd) ); return(position.x); }
void QFontEngineMac::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight) { QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; QTransform matrix; matrix.translate(x, y); getGlyphPositions(ti.glyphs, ti.num_glyphs, matrix, ti.flags, glyphs, positions); if (glyphs.size() == 0) return; CGContextSetFontSize(ctx, fontDef.pixelSize); CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight); CGAffineTransformConcat(cgMatrix, oldTextMatrix); if (synthesisFlags & QFontEngine::SynthesizedItalic) cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); cgMatrix = CGAffineTransformConcat(cgMatrix, multiEngine->transform); CGContextSetTextMatrix(ctx, cgMatrix); CGContextSetTextDrawingMode(ctx, kCGTextFill); QVarLengthArray<CGSize> advances(glyphs.size()); QVarLengthArray<CGGlyph> cgGlyphs(glyphs.size()); for (int i = 0; i < glyphs.size() - 1; ++i) { advances[i].width = (positions[i + 1].x - positions[i].x).toReal(); advances[i].height = (positions[i + 1].y - positions[i].y).toReal(); cgGlyphs[i] = glyphs[i]; } advances[glyphs.size() - 1].width = 0; advances[glyphs.size() - 1].height = 0; cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1]; CGContextSetFont(ctx, cgFont); CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal()); CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); if (synthesisFlags & QFontEngine::SynthesizedBold) { CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(), positions[0].y.toReal()); CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); } CGContextSetTextMatrix(ctx, oldTextMatrix); }
void drawMetaDataText (CGContextRef myContext, CGRect contextRect, CFURLRef url) { float w, h; w = contextRect.size.width; h = contextRect.size.height; //Lets pull some metadata! struct metaData struct_metaData; bzero(struct_metaData.Title, 1024); bzero(struct_metaData.Header, 1024); // bzero(struct_metaData.Expdata, 1024); // bzero(struct_metaData.Resolution, 1024); // bzero(struct_metaData.JrnlTitle, 1024); // bzero(struct_metaData.JrnlRef, 1024); // bzero(struct_metaData.Keywds, 4000); // bzero(struct_metaData.JrnlAuthor, 4000); exportMetaData(url, &struct_metaData); int wraplength = 50; int colLength = wraplength+5; int rowLength = 10; int textposX = 5; int textposY = 10; int calc_textposX = textposX; int calc_textposY = textposY; CGContextSetRGBFillColor (myContext, 1, 1, 1, 1); CGContextSelectFont (myContext, "Helvetica", 20, kCGEncodingMacRoman); CGContextSetCharacterSpacing (myContext, 1); CGContextSetTextDrawingMode (myContext, kCGTextFill); CGContextSetRGBFillColor(myContext, 0, 0, 0, 1); if(struct_metaData.Title[0] != 0){ calcRectangle("Title: ", struct_metaData.Title, rowLength, colLength, wraplength, &calc_textposX, &calc_textposY); drawRoundedRect(myContext, calc_textposX, calc_textposY); } DrawText("Title: ", struct_metaData.Title, myContext, rowLength, colLength, wraplength, &textposX, &textposY); }
static void cgSetPaintForText(CGContextRef cg, const SkPaint& paint) { SkColor c = paint.getColor(); CGFloat rgba[] = { SkColorGetB(c) / 255.0f, SkColorGetG(c) / 255.0f, SkColorGetR(c) / 255.0f, SkColorGetA(c) / 255.0f, }; CGContextSetRGBFillColor(cg, rgba[0], rgba[1], rgba[2], rgba[3]); CGContextSetTextDrawingMode(cg, kCGTextFill); CGContextSetFont(cg, typefaceToCGFont(paint.getTypeface())); CGContextSetFontSize(cg, SkScalarToFloat(paint.getTextSize())); CGContextSetAllowsFontSubpixelPositioning(cg, paint.isSubpixelText()); CGContextSetShouldSubpixelPositionFonts(cg, paint.isSubpixelText()); CGContextSetShouldAntialias(cg, paint.isAntiAlias()); CGContextSetShouldSmoothFonts(cg, paint.isLCDRenderText()); }
void GraphicsContext::setPlatformTextDrawingMode(int mode) { if (paintingDisabled()) return; // Wow, wish CG had used bits here. CGContextRef context = platformContext(); switch (mode) { case cTextInvisible: // Invisible CGContextSetTextDrawingMode(context, kCGTextInvisible); break; case cTextFill: // Fill CGContextSetTextDrawingMode(context, kCGTextFill); break; case cTextStroke: // Stroke CGContextSetTextDrawingMode(context, kCGTextStroke); break; case 3: // Fill | Stroke CGContextSetTextDrawingMode(context, kCGTextFillStroke); break; case cTextClip: // Clip CGContextSetTextDrawingMode(context, kCGTextClip); break; case 5: // Fill | Clip CGContextSetTextDrawingMode(context, kCGTextFillClip); break; case 6: // Stroke | Clip CGContextSetTextDrawingMode(context, kCGTextStrokeClip); break; case 7: // Fill | Stroke | Clip CGContextSetTextDrawingMode(context, kCGTextFillStrokeClip); break; default: break; } }
void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode) { if (paintingDisabled()) return; // Wow, wish CG had used bits here. CGContextRef context = platformContext(); switch (mode) { case TextModeInvisible: CGContextSetTextDrawingMode(context, kCGTextInvisible); break; case TextModeFill: CGContextSetTextDrawingMode(context, kCGTextFill); break; case TextModeStroke: CGContextSetTextDrawingMode(context, kCGTextStroke); break; case TextModeFill | TextModeStroke: CGContextSetTextDrawingMode(context, kCGTextFillStroke); break; case TextModeClip: CGContextSetTextDrawingMode(context, kCGTextClip); break; case TextModeFill | TextModeClip: CGContextSetTextDrawingMode(context, kCGTextFillClip); break; case TextModeStroke | TextModeClip: CGContextSetTextDrawingMode(context, kCGTextStrokeClip); break; case TextModeFill | TextModeStroke | TextModeClip: CGContextSetTextDrawingMode(context, kCGTextFillStrokeClip); break; default: break; } }
FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS * pCharPos, CFX_Font * pFont, CFX_FontCache * pCache, const CFX_AffineMatrix * pObject2Device, FX_FLOAT font_size, FX_DWORD argb, int alpha_flag, void* pIccTransform) { if (!pFont) { return FALSE; } FX_BOOL bBold = pFont->IsBold(); if (!bBold && pFont->GetSubstFont() && pFont->GetSubstFont()->m_Weight >= 500 && pFont->GetSubstFont()->m_Weight <= 600) { return FALSE; } for (int i = 0; i < nChars; i ++) { if (pCharPos[i].m_bGlyphAdjust) { return FALSE; } } CGContextRef ctx = CGContextRef(m_pPlatformGraphics); if (NULL == ctx) { return FALSE; } CGContextSaveGState(ctx); CGContextSetTextDrawingMode(ctx, kCGTextFillClip); CGRect rect_cg; CGImageRef pImageCG = NULL; if (m_pClipRgn) { rect_cg = CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height()); const CFX_DIBitmap* pClipMask = m_pClipRgn->GetMask(); if (pClipMask) { CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData(NULL, pClipMask->GetBuffer(), pClipMask->GetPitch() * pClipMask->GetHeight(), _DoNothing); CGFloat decode_f[2] = {255.f, 0.f}; pImageCG = CGImageMaskCreate(pClipMask->GetWidth(), pClipMask->GetHeight(), 8, 8, pClipMask->GetPitch(), pClipMaskDataProvider, decode_f, FALSE); CGDataProviderRelease(pClipMaskDataProvider); } } else { rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight()); } rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg); if (pImageCG) { CGContextClipToMask(ctx, rect_cg, pImageCG); } else { CGContextClipToRect(ctx, rect_cg); } FX_BOOL ret = _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, font_size, argb, alpha_flag, pIccTransform); if (pImageCG) { CGImageRelease(pImageCG); } CGContextRestoreGState(ctx); return ret; }
PlatformFont::CharInfo& MacCarbFont::getCharInfo(const UTF16 ch) const { // We use some static data here to avoid re allocating the same variable in a loop. // this func is primarily called by GFont::loadCharInfo(), Rect imageRect; CGContextRef imageCtx; U32 bitmapDataSize; ATSUTextMeasurement tbefore, tafter, tascent, tdescent; OSStatus err; // 16 bit character buffer for the ATUSI calls. // -- hey... could we cache this at the class level, set style and loc *once*, // then just write to this buffer and clear the layout cache, to speed up drawing? static UniChar chUniChar[1]; chUniChar[0] = ch; // Declare and clear out the CharInfo that will be returned. static PlatformFont::CharInfo c; dMemset(&c, 0, sizeof(c)); // prep values for GFont::addBitmap() c.bitmapIndex = 0; c.xOffset = 0; c.yOffset = 0; // put the text in the layout. // we've hardcoded a string length of 1 here, but this could work for longer strings... (hint hint) // note: ATSUSetTextPointerLocation() also clears the previous cached layout information. ATSUSetTextPointerLocation( mLayout, chUniChar, 0, 1, 1); ATSUSetRunStyle( mLayout, mStyle, 0,1); // get the typographic bounds. this tells us how characters are placed relative to other characters. ATSUGetUnjustifiedBounds( mLayout, 0, 1, &tbefore, &tafter, &tascent, &tdescent); c.xIncrement = FixedToInt(tafter); // find out how big of a bitmap we'll need. // as a bonus, we also get the origin where we should draw, encoded in the Rect. ATSUMeasureTextImage( mLayout, 0, 1, 0, 0, &imageRect); U32 xFudge = 2; U32 yFudge = 1; c.width = imageRect.right - imageRect.left + xFudge; // add 2 because small fonts don't always have enough room c.height = imageRect.bottom - imageRect.top + yFudge; c.xOrigin = imageRect.left; // dist x0 -> center line c.yOrigin = -imageRect.top; // dist y0 -> base line // kick out early if the character is undrawable if( c.width == xFudge || c.height == yFudge) return c; // allocate a greyscale bitmap and clear it. bitmapDataSize = c.width * c.height; c.bitmapData = new U8[bitmapDataSize]; dMemset(c.bitmapData,0x00,bitmapDataSize); // get a graphics context on the bitmap imageCtx = CGBitmapContextCreate( c.bitmapData, c.width, c.height, 8, c.width, mColorSpace, kCGImageAlphaNone); if(!imageCtx) { Con::errorf("Error: failed to create a graphics context on the CharInfo bitmap! Drawing a blank block."); c.xIncrement = c.width; dMemset(c.bitmapData,0x0F,bitmapDataSize); return c; } // Turn off antialiasing for monospaced console fonts. yes, this is cheating. if(mSize < 12 && ( dStrstr(mName,"Monaco")!=NULL || dStrstr(mName,"Courier")!=NULL )) CGContextSetShouldAntialias(imageCtx, false); // Set up drawing options for the context. // Since we're not going straight to the screen, we need to adjust accordingly CGContextSetShouldSmoothFonts(imageCtx, false); CGContextSetRenderingIntent(imageCtx, kCGRenderingIntentAbsoluteColorimetric); CGContextSetInterpolationQuality( imageCtx, kCGInterpolationNone); CGContextSetGrayFillColor( imageCtx, 1.0, 1.0); CGContextSetTextDrawingMode( imageCtx, kCGTextFill); // tell ATSUI to substitute fonts as needed for missing glyphs ATSUSetTransientFontMatching(mLayout, true); // set up three parrallel arrays for setting up attributes. // this is how most options in ATSUI are set, by passing arrays of options. ATSUAttributeTag theTags[] = { kATSUCGContextTag }; ByteCount theSizes[] = { sizeof(CGContextRef) }; ATSUAttributeValuePtr theValues[] = { &imageCtx }; // bind the layout to the context. ATSUSetLayoutControls( mLayout, 1, theTags, theSizes, theValues ); // Draw the character! int yoff = c.height < 3 ? 1 : 0; // kludge for 1 pixel high characters, such as '-' and '_' int xoff = 1; err = ATSUDrawText( mLayout, 0, 1, IntToFixed(-imageRect.left + xoff), IntToFixed(imageRect.bottom + yoff ) ); CGContextRelease(imageCtx); if(err != noErr) { Con::errorf("Error: could not draw the character! Drawing a blank box."); dMemset(c.bitmapData,0x0F,bitmapDataSize); } #if TORQUE_DEBUG // Con::printf("Font Metrics: Rect = %2i %2i %2i %2i Char= %C, 0x%x Size= %i, Baseline= %i, Height= %i",imageRect.top, imageRect.bottom, imageRect.left, imageRect.right,ch,ch, mSize,mBaseline, mHeight); // Con::printf("Font Bounds: left= %2i right= %2i Char= %C, 0x%x Size= %i",FixedToInt(tbefore), FixedToInt(tafter), ch,ch, mSize); #endif return c; }
// Draws the current ATSUI data. Takes a GrafPtr as an argument so // that it can handle printing as well as drawing into a window. // void DrawATSUIStuff(GrafPtr drawingPort) { GrafPtr savedPort; Rect portBounds, quarterRect2, quarterRect3; float windowHeight, quarter; CGContextRef context; TXNTextBoxOptionsData optionsData; Boolean needToUseCGStrokeMethod; // Set up the GrafPort GetPort(&savedPort); SetPort(drawingPort); GetPortBounds(drawingPort, &portBounds); EraseRect(&portBounds); // Divide the window into vertical quarters, and draw the text in the middle two quarters windowHeight = portBounds.bottom - portBounds.top; quarter = windowHeight / 4.0; MacSetRect(&quarterRect2, portBounds.left, portBounds.top + quarter, portBounds.right, portBounds.bottom - (quarter * 2.0)); FrameRect(&quarterRect2); MacSetRect(&quarterRect3, portBounds.left, portBounds.top + (quarter * 2.0), portBounds.right, portBounds.bottom - quarter); FrameRect(&quarterRect3); // Set up the CGContext if (gNewCG) QDBeginCGContext(drawingPort, &context); else CreateCGContextForPort(drawingPort, &context); // Setup the options to pass into TXNDrawUnicodeTextBox optionsData.optionTags = kTXNUseCGContextRefMask | kTXNSetFlushnessMask | kTXNUseFontFallBackMask; optionsData.flushness = X2Frac(0.5); // Center the text horizontally, just for this demo. optionsData.options = (void *)context; // This parameter really needs to be renamed, see 3198383. // Draw the text once without the extr bold verify_noerr( TXNDrawUnicodeTextBox(gText, gLength, &quarterRect2, gStyle, &optionsData) ); // ---------------------------------------------------------- // // Here is where we change the setting to do the extra stroke // The value of gStrokeThicknessFactor determines how thick the extra stroke is. // The "standard" value used by ATSUI is 0.024; // this was changed to 0.044 for bug 3189696, // and will probably be changed back, so if you // want the extra stroke, you will have to do it // manually, as is done below. // // The extra stroke method: // - will look good on-screen when CG anti-aliasing is ON // - will look good when printing // - will *NOT* look good on-screen when CG anti-aliasing is OFF // (just use kATSUQDBoldfaceTag in that case) // needToUseCGStrokeMethod = gCurrentlyPrinting || IsAntiAliased(gPointSize); if ( needToUseCGStrokeMethod ) { CGContextSaveGState(context); CGContextSetTextDrawingMode(context, kCGTextFillStroke); CGContextSetLineWidth(context, gStrokeThicknessFactor * Fix2X(gPointSize)); // You might want to call CGContextSetStrokeColor() here, // just to make certain it is the same as the text/fill color. } else MySetBoldfaceTag(gStyle); // This will look very strong on-screen when CG anti-aliasing is off // Draw the text again with the extra bold for comparison verify_noerr( TXNDrawUnicodeTextBox(gText, gLength, &quarterRect3, gStyle, &optionsData) ); // Undo the previous CG text mode setting if ( needToUseCGStrokeMethod ) CGContextRestoreGState(context); else MyClearBoldfaceTag(gStyle); // Tear down the CGContext since we are done with it if (gNewCG) QDEndCGContext(drawingPort, &context); else CGContextRelease(context); // Restore the GrafPort SetPort(savedPort); }
void map_text(MapGC *mgc, MapSettings *settings, int x, int y, const char *text, int style) { if (FALSE); #ifdef HAVE_CAIRO else if (mgc->cairo_cr) { int xpos = x; int ypos = y; cairo_text_extents_t extents; cairo_select_font_face(mgc->cairo_cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); if (style & 0x800) { if (settings->pdamode) cairo_set_font_size(mgc->cairo_cr, 9); else cairo_set_font_size(mgc->cairo_cr, 14); } else { if (settings->pdamode) cairo_set_font_size(mgc->cairo_cr, 8); else cairo_set_font_size(mgc->cairo_cr, 11); } cairo_text_extents(mgc->cairo_cr, text, &extents); if ((style & 0x300) == 0x100) { xpos -= extents.width; } else if ((style & 0x300) == 0x200) { xpos -= extents.width / 2; } else if ((style & 0x300) == 0x300) { xpos -= extents.width / 2; ypos -= extents.height / 2; } if (style & 0x400) map_bkg_rectangle(mgc, settings, xpos, ypos, extents.width, extents.height); if (style & 1) cairo_set_source_rgb(mgc->cairo_cr, 0, 0, 1); else cairo_set_source_rgb(mgc->cairo_cr, 0, 0, 0); cairo_move_to(mgc->cairo_cr, xpos, ypos + extents.height); cairo_show_text(mgc->cairo_cr, text); } #endif #ifdef HAVE_GTK else if (mgc->gtk_drawable) { int xpos = x; int ypos = y; int width; int height; PangoFontDescription *fd; PangoLayout *layout = gtk_widget_create_pango_layout(mgc->gtk_widget, text); if (style & 0x800) { if (settings->pdamode) fd = pango_font_description_from_string("Sans 9"); else fd = pango_font_description_from_string("Sans 14"); } else { if (settings->pdamode) fd = pango_font_description_from_string("Sans 8"); else fd = pango_font_description_from_string("Sans 11"); } pango_layout_set_font_description(layout, fd); pango_layout_get_pixel_size(layout, &width, &height); if ((style & 0x300) == 0x100) { xpos -= width; } else if ((style & 0x300) == 0x200) { xpos -= width / 2; } else if ((style & 0x300) == 0x300) { xpos -= width / 2; ypos -= height / 2; } if (style & 0x400) map_bkg_rectangle(mgc, settings, xpos, ypos, width, height); if (style & 1) gdk_draw_layout_with_colors(mgc->gtk_drawable, mgc->gtk_gc, xpos, ypos, layout, &settings->blue, NULL); else gdk_draw_layout_with_colors(mgc->gtk_drawable, mgc->gtk_gc, xpos, ypos, layout, &settings->black, NULL); if (layout != NULL) g_object_unref(G_OBJECT(layout)); pango_font_description_free(fd); } #endif #ifdef HAVE_QT else if (mgc->qt_painter) { qt_text(mgc->qt_painter, settings, x, y, text, style); } #endif #ifdef HAVE_QUARTZ else if (mgc->quartz_gc) { int xpos = x; int ypos = y; int width; int height; CGContextSelectFont(mgc->quartz_gc, "Verdana", 8, kCGEncodingMacRoman); if (style & 0x800) { if (settings->pdamode) CGContextSetFontSize(mgc->quartz_gc, 9); else CGContextSetFontSize(mgc->quartz_gc, 14); } else { if (settings->pdamode) CGContextSetFontSize(mgc->quartz_gc, 8); else CGContextSetFontSize(mgc->quartz_gc, 11); } { CGPoint oldPos = CGContextGetTextPosition(mgc->quartz_gc); CGContextSetTextDrawingMode(mgc->quartz_gc, kCGTextInvisible); CGContextShowText(mgc->quartz_gc, text, strlen(text)); CGPoint newPos = CGContextGetTextPosition(mgc->quartz_gc); CGContextSetTextDrawingMode(mgc->quartz_gc, kCGTextFill); CGContextSetTextPosition(mgc->quartz_gc, oldPos.x, oldPos.y); width = newPos.x - oldPos.x; } if ((style & 0x300) == 0x100) { xpos -= width; } else if ((style & 0x300) == 0x200) { xpos -= width / 2; } else if ((style & 0x300) == 0x300) { xpos -= width / 2; ypos -= height / 2; } if (style & 0x400) map_bkg_rectangle(mgc, settings, xpos, ypos, width, height); if (style & 1) CGContextSetRGBStrokeColor(mgc->quartz_gc, 0, 0, 1, 1); else CGContextSetRGBStrokeColor(mgc->quartz_gc, 0, 0, 0, 1); CGContextSetTextPosition(mgc->quartz_gc, xpos, ypos); CGContextShowText(mgc->quartz_gc, text, strlen(text)); } #endif #ifdef WIN32 else if (mgc->win_dc) { int xpos = x; int ypos = y; int fontSize; HFONT oldFont; HFONT font; SIZE textSize; if (style & 0x800) { if (settings->pdamode) fontSize = 9; else fontSize = 14; } else { if (settings->pdamode) fontSize = 8; else fontSize = 11; } fontSize = fontSize * 3 / 2; font = CreateFont(fontSize, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "MSSansSerif"); oldFont = SelectObject(mgc->win_dc, font); GetTextExtentPoint32(mgc->win_dc, text, strlen(text), &textSize); if ((style & 0x300) == 0x100) { xpos -= textSize.cx; } else if ((style & 0x300) == 0x200) { xpos -= textSize.cx / 2; } else if ((style & 0x300) == 0x300) { xpos -= textSize.cx / 2; ypos -= textSize.cy / 2; } if (style & 0x400) map_bkg_rectangle(mgc, settings, xpos, ypos, textSize.cx, textSize.cy); if (style & 1) SetTextColor(mgc->win_dc, RGB(0x00, 0x00, 0xff)); else SetTextColor(mgc->win_dc, RGB(0x00, 0x00, 0x00)); SetBkMode(mgc->win_dc, TRANSPARENT); TextOut(mgc->win_dc, xpos, ypos, text, strlen(text)); SelectObject(mgc->win_dc, oldFont); DeleteObject(font); } #endif }
FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color, int alpha_flag , void* pIccTransform) { if (NULL == pFont || NULL == _context) { return FALSE; } FX_BOOL bBold = pFont->IsBold(); if (!bBold && pFont->GetSubstFont() && pFont->GetSubstFont()->m_Weight >= 500 && pFont->GetSubstFont()->m_Weight <= 600) { return FALSE; } SaveState(); CGContextSetTextDrawingMode(_context, kCGTextFillClip); FX_BOOL ret = FALSE; FX_INT32 i = 0; while (i < nChars) { if (pCharPos[i].m_bGlyphAdjust || font_size < 0) { if (i > 0) { ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, font_size, color, alpha_flag, pIccTransform); if (!ret) { RestoreState(FALSE); return ret; } } const FXTEXT_CHARPOS* char_pos = pCharPos + i; CFX_AffineMatrix glphy_matrix; if (font_size < 0) { glphy_matrix.Concat(-1, 0, 0, -1, 0, 0); } if (char_pos->m_bGlyphAdjust) { glphy_matrix.Concat(char_pos->m_AdjustMatrix[0], char_pos->m_AdjustMatrix[1], char_pos->m_AdjustMatrix[2], char_pos->m_AdjustMatrix[3], 0, 0); } ret = CG_DrawGlypRun(1, char_pos, pFont, pCache, &glphy_matrix, pObject2Device, font_size, color, alpha_flag, pIccTransform); if (!ret) { RestoreState(FALSE); return ret; } i ++; pCharPos += i; nChars -= i; i = 0; } else { i ++; } } if (i > 0) { ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, font_size, color, alpha_flag, pIccTransform); } RestoreState(FALSE); return ret; }
QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) { const glyph_metrics_t br = boundingBox(glyph); QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32); im.fill(0); CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) uint cgflags = kCGImageAlphaNoneSkipFirst; #ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) cgflags |= kCGBitmapByteOrder32Host; #endif #else CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst; #endif CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), 8, im.bytesPerLine(), colorspace, cgflags); CGColorSpaceRelease(colorspace); CGContextSetFontSize(ctx, fontDef.pixelSize); CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias)); CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); CGAffineTransformConcat(cgMatrix, oldTextMatrix); if (synthesisFlags & QFontEngine::SynthesizedItalic) cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0)); cgMatrix = CGAffineTransformConcat(cgMatrix, multiEngine->transform); CGContextSetTextMatrix(ctx, cgMatrix); CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); CGContextSetTextDrawingMode(ctx, kCGTextFill); CGContextSetFont(ctx, cgFont); qreal pos_x = -br.x.toReal()+1, pos_y = im.height()+br.y.toReal(); CGContextSetTextPosition(ctx, pos_x, pos_y); CGSize advance; advance.width = 0; advance.height = 0; CGGlyph cgGlyph = glyph; CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); if (synthesisFlags & QFontEngine::SynthesizedBold) { CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y); CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); } CGContextRelease(ctx); QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); QVector<QRgb> colors(256); for (int i=0; i<256; ++i) colors[i] = qRgba(0, 0, 0, i); indexed.setColorTable(colors); for (int y=0; y<im.height(); ++y) { uint *src = (uint*) im.scanLine(y); uchar *dst = indexed.scanLine(y); for (int x=0; x<im.width(); ++x) { *dst = qGray(*src); ++dst; ++src; } } return indexed; }
static void Quartz_MetricInfo(int c, R_GE_gcontext *gc, double* ascent, double* descent, double* width, NewDevDesc *dd) { FMetricRec myFMetric; QuartzDesc *xd = (QuartzDesc *) dd-> deviceSpecific; char testo[2]; char *ff; CGrafPtr savedPort; Rect bounds; CGPoint position; unsigned char tmp; testo[0] = c; testo[1] = '\0'; /* fprintf(stderr,"c=%c,>%s<\n",c,testo); */ GetPort(&savedPort); SetPort(GetWindowPort(xd->window)); Quartz_SetFont(gc->fontfamily, gc->fontface, gc->cex, gc->ps, dd); if(c==0){ FontMetrics(&myFMetric); *ascent = xd->yscale *floor(gc->cex * gc->ps + 0.5) * FixedToFloat(myFMetric.ascent); *descent = xd->yscale*floor(gc->cex * gc->ps + 0.5) * FixedToFloat(myFMetric.descent); } else { CGContextSaveGState( GetContext(xd) ); CGContextTranslateCTM( GetContext(xd), 0, 0 ); CGContextScaleCTM( GetContext(xd), -1, 1); CGContextRotateCTM( GetContext(xd), -1.0 * 3.1416); CGContextSetTextDrawingMode( GetContext(xd), kCGTextInvisible ); Quartz_SetFont(gc->fontfamily, gc->fontface, gc->cex, gc->ps, dd); ff = Quartz_TranslateFontFamily(gc->fontfamily, gc->fontface, xd->family); tmp = (unsigned char)c; if( (gc->fontface == 5) || (strcmp(ff,"Symbol")==0)){ if( (tmp>31) && IsThisASymbol(tmp)) testo[0] = (char)Lat2Uni[tmp-31-1]; else Quartz_SetFont(gc->fontfamily, -1, gc->cex, gc->ps, dd); } else { if(tmp>127) testo[0] = (char)Lat2Mac[tmp-127-1]; } CGContextShowTextAtPoint( GetContext(xd), 0, 0, testo, 1 ); position = CGContextGetTextPosition( GetContext(xd) ); CGContextRestoreGState( GetContext(xd) ); QDTextBounds(1,testo,&bounds); *ascent = -bounds.top; *descent = bounds.bottom; *width = bounds.right - bounds.left; *width = position.x; } SetPort(savedPort); /* fprintf(stderr,"ascent=%f, descent=%f,width=%f\n",*ascent, *descent, *width); */ return; }
static void Quartz_Text(double x, double y, char *str, double rot, double hadj, R_GE_gcontext *gc, NewDevDesc *dd) { int len,i; char *buf=NULL; char *ff; char symbuf; unsigned char tmp; QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific; CGContextSaveGState( GetContext(xd) ); CGContextTranslateCTM( GetContext(xd), x, y ); CGContextScaleCTM( GetContext(xd) , -1, 1); CGContextRotateCTM( GetContext(xd) , (-1.0 + 2*rot/360) * 3.1416); Quartz_SetStroke( gc->col, gc->gamma, dd); CGContextSetTextDrawingMode( GetContext(xd), kCGTextFill ); Quartz_SetFill(gc->col, gc->gamma, dd); Quartz_SetFont(gc->fontfamily, gc->fontface, gc->cex, gc->ps, dd); len = strlen(str); ff = Quartz_TranslateFontFamily(gc->fontfamily, gc->fontface, xd->family); if( ((gc->fontface == 5) || (strcmp(ff,"Symbol")==0)) && (len==1) ){ tmp = (unsigned char)str[0]; if(tmp>31) symbuf = (char)Lat2Uni[tmp-31-1]; else symbuf = str[0]; if( !IsThisASymbol(tmp) ){ Quartz_SetFont(gc->fontfamily, -1, gc->cex, gc->ps, dd); symbuf = str[0]; } if(WeAreOnPanther) CGContextShowTextAtPoint( GetContext(xd), 0, 0, &symbuf, len ); else CGContextShowTextAtPoint( GetContext(xd), 0, 0, str, len ); } else { if( (buf = malloc(len)) != NULL){ if( strcmp(ff,"Symbol")==0){ for(i=0;i <len;i++){ tmp = (unsigned char)str[i]; if(tmp>31) buf[i] = (char)Lat2Uni[tmp-31-1]; else buf[i] = str[i]; } } else { for(i=0;i <len;i++){ tmp = (unsigned char)str[i]; if(tmp>127) buf[i] = (char)Lat2Mac[tmp-127-1]; else buf[i] = str[i]; } } CGContextShowTextAtPoint( GetContext(xd), 0, 0, buf, len ); free(buf); } } CGContextRestoreGState( GetContext(xd) ); }
void CGContextSetTextDrawingMode_wrap(CGContext *con, int j) { CGContextSetTextDrawingMode(con, CGTextDrawingMode(j)); }
void x_async_refresh(CGContextRef myContext,CGRect myBoundingBox) { #ifdef ENABLEQD CEmulatorMac* pEmu = (CEmulatorMac*)CEmulator::theEmulator; if (!pEmu) return ; #endif #ifndef DRIVER_IOS x_vbl_count++; #endif addFrameRate(0); CHANGE_BORDER(1,0xFF); // OG if (macUsingCoreGraphics) { if(r_sim65816.is_emulator_offscreen_available() && g_kimage_offscreen.dev_handle) { /* void addConsoleWindow(Kimage* _dst); addConsoleWindow(&g_kimage_offscreen); */ CGContextSaveGState(myContext); #ifndef DRIVER_IOS // CGContextTranslateCTM(myContext,0.0, X_A2_WINDOW_HEIGHT); CGContextTranslateCTM(myContext,0.0, myBoundingBox.size.height); CGContextScaleCTM(myContext,1.0,-1.0); #endif CGImageRef myImage = CGBitmapContextCreateImage((CGContextRef)g_kimage_offscreen.dev_handle); CGContextDrawImage(myContext, myBoundingBox, myImage);// 6 #ifndef VIDEO_SINGLEVLINE if (r_sim65816.get_video_fx() == VIDEOFX_CRT) { CGContextSetRGBFillColor(myContext,0,0,0,0.5); for(int h=0;h<g_kimage_offscreen.height;h+=2) { CGRect r = CGRectMake(0,h,g_kimage_offscreen.width_act,1); CGContextFillRect(myContext,r); } } #endif CGImageRelease(myImage); CGContextRestoreGState(myContext); #ifndef DRIVER_IOS if (!messageLine.IsEmpty()) { CGContextSaveGState(myContext); CGContextSetTextMatrix(myContext,CGAffineTransformIdentity); CGContextTranslateCTM(myContext,0.0, X_A2_WINDOW_HEIGHT); CGContextScaleCTM(myContext,1.0,-1.0); CGContextSelectFont(myContext, "Courier", 14.0, kCGEncodingMacRoman); CGContextSetTextDrawingMode(myContext, kCGTextFill); CGContextSetRGBFillColor (myContext, 1,1, 1, 1); CGContextSetShouldAntialias(myContext, true); #define SHADOW 4.0 CGFloat myColorValues[] = {0.5, 0.5, 0.5, 1.0}; CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB ();// 9 CGColorRef myColor = CGColorCreate (myColorSpace, myColorValues); CGContextSetShadowWithColor(myContext, CGSizeMake(SHADOW, -SHADOW), 4, myColor //CGColorCreateGenericGray(0.5,1.0) ); CGContextShowTextAtPoint(myContext, 20.0, X_A2_WINDOW_HEIGHT-20.0, messageLine.c_str(), messageLine.GetLength()); CGContextRestoreGState(myContext); messageLineVBL--; if (messageLineVBL<0) messageLine.Empty(); else x_refresh_video(); } #endif } else { CGContextSaveGState(myContext); #if defined(DRIVER_IOS) // efface en noir si l'émulateur n'avait pas encore démarré (le cas sur 3GS) CGContextSetRGBFillColor (myContext, 0, 0, 0, 1); #else CGContextSetRGBFillColor (myContext, 0, 0, 1, 1); #endif CGContextFillRect (myContext, CGRectMake (0, 0, X_A2_WINDOW_WIDTH, X_A2_WINDOW_HEIGHT)); CGContextRestoreGState(myContext); } } else { #ifdef ENABLEQD CGrafPtr window_port = pEmu->window_port; Rect src_rect; Rect dest_rect; SetRect(&src_rect,0,0,704,462); SetRect(&dest_rect,0,0,704,462); if (pixmap_backbuffer) CopyBits( (BitMap *)(*pixmap_backbuffer), GetPortBitMapForCopyBits(window_port), &src_rect, &dest_rect, srcCopy, NULL); #endif } CHANGE_BORDER(1,0); if (r_sim65816.is_emulator_offscreen_available() && g_driver.x_handle_state_on_paint) g_driver.x_handle_state_on_paint(myBoundingBox.size.width,myBoundingBox.size.height); }
PsychError SCREENTestTexture(void) { #if PSYCH_SYSTEM == PSYCH_OSX PsychWindowRecordType *winRec; CGContextRef cgContext; unsigned int memoryTotalSizeBytes, memoryRowSizeBytes; UInt32 *textureMemory; int stringLength, totalTexels, i; GLuint myTexture; CGColorSpaceRef cgColorSpace; //all subfunctions should have these two lines. PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; //Get the window structure for the onscreen window. It holds the onscreein GL context which we will need in the //final step when we copy the texture from system RAM onto the screen. PsychErrorExit(PsychCapNumInputArgs(1)); PsychErrorExit(PsychRequireNumInputArgs(1)); PsychErrorExit(PsychCapNumOutputArgs(1)); PsychAllocInWindowRecordArg(1, TRUE, &winRec); if(!PsychIsOnscreenWindow(winRec)) PsychErrorExitMsg(PsychError_user, "Onscreen window pointer required"); //allocate memory for the surface memoryRowSizeBytes=sizeof(UInt32) * textureSizeX; memoryTotalSizeBytes= memoryRowSizeBytes * textureSizeY; textureMemory=(UInt32 *)malloc(memoryTotalSizeBytes); if(!textureMemory) PsychErrorExitMsg(PsychError_internal, "Failed to allocate surface memory\n"); if(useQuartz){ //Create the Core Graphics bitmap graphics context. We have to be careful to specify arguments which will allow us to store the texture as an OpenGL texture. //The choice of color space needs to be checked. cgColorSpace=CGColorSpaceCreateDeviceRGB(); cgContext= CGBitmapContextCreate(textureMemory, textureSizeX, textureSizeY, cg_RGBA_32_BitsPerComponent, memoryRowSizeBytes, cgColorSpace, cg_RGBA_32_AlphaOption); if(!cgContext){ free((void *)textureMemory); PsychErrorExitMsg(PsychError_internal, "Failed to allocate CG Bimap Context\n"); } // Draw some text into the bitmap context. We need to set font, size, pen (drawing mode), color, alpha, text position. // There are two ways to select the font in a Core Graphics Quartz context depending on the type of font. // 1) CGContextSetFont() for Apple Type Services (ATS) font aka "The Right Way" // A) call CGFontCreateWithPlatformFont() which returns a CGFontRef // B) call CGContextSetFont() to set the font to be the drawing font within a context. // 2) CGContextSelectFont() for MacRoman aka "How We Do It" // // Using MacRoman seems to mean that we just change the coding, though CGContextSelectFont(). For info on using ATS fonts see: // http://developer.apple.com/documentation/Carbon/Reference/ATS/ CGContextSelectFont(cgContext, "Helvetica", (float)24, kCGEncodingMacRoman); //set the font and its size. CGContextSetTextDrawingMode(cgContext, kCGTextFill); //set the pen to be a filled pen CGContextSetRGBStrokeColor(cgContext, (float)0.5, (float)0.5, (float)0.0, (float)1.0); //set the stroke color and alpha CGContextSetRGBFillColor(cgContext, (float)0.5, (float)0.5, (float)0.0, (float)1.0); //set the fill color and alpha stringLength=strlen(textString); CGContextShowTextAtPoint(cgContext, (float)textPositionX, (float)textPositionY, textString, stringLength); //draw at specified location. CGContextFlush(cgContext); //this might not be necessary but do it just in case. }else{ //fill the texture memory by poking bits in the array which will be turned into a texture. totalTexels=textureSizeX * textureSizeY; for(i=0;i<totalTexels;i++) textureMemory[i]= redFill << 24 | greenFill | 16 << blueFill << 8 | alphaFill; } //Convert the CG graphics bitmap (Quartz surface) into a CG texture. GL thinks we are loading the texture from memory we indicate to glTexImage2D, but really //we are just setting the texture to share the same memory as the Quartz surface. PsychSetGLContext(winRec); glEnable(GL_TEXTURE_RECTANGLE_EXT); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glGenTextures(1, &myTexture); //create an index "name" for our texture glBindTexture(GL_TEXTURE_RECTANGLE_EXT, myTexture); //instantiate a texture of type associated with the index and set it to be the target for subsequent gl texture operators. glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1); //tell gl how to unpack from our memory when creating a surface, namely don't really unpack it but use it for texture storage. glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //specify interpolation scaling rule for copying from texture. glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //specify interpolation scaling rule from copying from texture. glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, textureSizeX, textureSizeY, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, textureMemory); //Copy the texture to the display. What are the s and t indices of the first pixel of the texture ? 0 or 1 ? //set the GL context to be the onscreen window glBegin(GL_QUADS); glTexCoord2d(0.0, 0.0); glVertex2d(0.0, 0.0); glTexCoord2d(textureSizeX, 0.0 ); glVertex2d(textureSizeX, 0.0); glTexCoord2d(textureSizeX, textureSizeY); glVertex2d(textureSizeX, textureSizeY); glTexCoord2d(0.0, textureSizeY); glVertex2d(0.0, textureSizeY); glEnd(); glFlush(); glDisable(GL_TEXTURE_RECTANGLE_EXT); //Close up shop. Unlike with normal textures is important to release the context before deallocating the memory which glTexImage2D() was given. //First release the GL context, then the CG context, then free the memory. glDeleteTextures(1, &myTexture); //Remove references from gl to the texture memory & free gl's associated resources if(useQuartz) CGContextRelease(cgContext); //Remove references from Core Graphics to the texture memory & free Core Graphics' associated resources. free((void *)textureMemory); //Free the memory #endif return(PsychError_none); }