// This function is needed to work around a bug in Windows CG <rdar://problem/22703470> void PlatformCALayer::drawTextAtPoint(CGContextRef context, CGFloat x, CGFloat y, CGSize scale, CGFloat fontSize, const char* text, size_t length) const { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" CGContextSetTextMatrix(context, CGAffineTransformMakeScale(scale.width, scale.height)); CGContextSelectFont(context, "Helvetica", fontSize, kCGEncodingMacRoman); CGContextShowTextAtPoint(context, x, y, text, length); #pragma clang diagnostic pop }
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); }
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); }
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); }
static void drawMarks(CGContextRef gc, int width, int height, int max) { float angle, c, s, tick, radius, needle; float r0, r1, r2, r3, cx, cy; int i, start, end, redline, section; cx = CENTERX * width; cy = CENTERY * height; redline = TICKS * SUBTICKS * 0.8; radius = 0.5 * (width > height ? width : height); needle = radius * 0.85; for (section = 0; section < 2; section++) { start = section ? redline + 1 : 0; end = section ? TICKS * SUBTICKS : redline; if (section) CGContextSetRGBStrokeColor(gc, 1.0, 0.1, 0.1, 1.0); else CGContextSetRGBStrokeColor(gc, 0.9, 0.9, 1.0, 1.0); // inner tick ring r0 = 0.97 * needle; r1 = 1.04 * needle; r2 = 1.00 * needle; r3 = 1.01 * needle; for (i = start; i <= end ; i++) { tick = i / (float)(SUBTICKS * TICKS); angle = (2.0 / 3.0) * (2 * M_PI) * tick - M_PI / 6; c = cos(angle); s = sin(angle); if (i % SUBTICKS != 0) { CGContextMoveToPoint(gc, cx - r0*c, cy + r0*s); CGContextAddLineToPoint(gc, cx - r1*c, cy + r1*s); } else { CGContextMoveToPoint(gc, cx - r2*c, cy + r2*s); CGContextAddLineToPoint(gc, cx - r3*c, cy + r3*s); } } CGContextSetLineWidth(gc, 2.0); CGContextStrokePath(gc); // outer tick ring start = ((float)start / SUBTICKS) + section; end = ((float)end / SUBTICKS); r0 = 1.05 * needle; r1 = 1.14 * needle; for (i = start; i <= end ; i++) { tick = i / (float)(TICKS); angle = (2.0 / 3.0) * (2 * M_PI) * tick - M_PI / 6; c = cos(angle); s = sin(angle); CGContextMoveToPoint(gc, cx - r0*c, cy + r0*s); CGContextAddLineToPoint(gc, cx - r1*c, cy + r1*s); } CGContextSetLineWidth(gc, 3.0); CGContextStrokePath(gc); } CGContextSelectFont(gc, "Arial Bold Italic", 20.0, kCGEncodingMacRoman); r0 = 0.82 * needle; for (i = 0 ; i <= max ; i += (max / TICKS)) { char text[20]; float dx, dy; sprintf(text, "%d", i); // hardcoded text centering for this font size { if (i > 199) dx = -18; else if (i > 99) dx = -17; else if (i > 0) dx = -14; else dx = -12; dy = -6.0; } angle = (2.0 / 3.0) * (2 * M_PI) * i / max - M_PI / 6; c = cos(angle); s = sin(angle); CGContextShowTextAtPoint(gc, cx - r0*c + dx, cy + r0*s + dy, text, strlen(text)); } }
void CGContextSelectFont_wrap(CGContext* c, const char* s, float siz) { return CGContextSelectFont(c, s, siz, kCGEncodingMacRoman); }
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 }
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); }