Example #1
0
def add_menu_item(menu, title, action, key):
    with AutoReleasePool():
        title = cocoapy.CFSTR(title)
        action = cocoapy.get_selector(action)
        key = cocoapy.CFSTR(key)
        menuItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
            title, action, key)
        menu.addItem_(menuItem)

        # cleanup
        title.release()
        key.release()
        menuItem.release()
Example #2
0
 def have_font(cls, name):
     name = str(name)
     if name in cls._loaded_CGFont_table: return True
     # Try to create the font to see if it exists.
     # TODO: Find a better way to check.
     cfstring = cocoapy.CFSTR(name)
     cgfont = c_void_p(quartz.CGFontCreateWithFontName(cfstring))
     cf.CFRelease(cfstring)
     if cgfont:
         cf.CFRelease(cgfont)
         return True
     return False
Example #3
0
 def __init__(self):
     super(CocoaEventLoop, self).__init__()
     with AutoReleasePool():
         # Prepare the default application.
         self.NSApp = NSApplication.sharedApplication()
         if self.NSApp.isRunning():
             # Application was already started by GUI library (e.g. wxPython).
             return
         if not self.NSApp.mainMenu():
             create_menu()
         self.NSApp.setActivationPolicy_(
             cocoapy.NSApplicationActivationPolicyRegular)
         # Prevent Lion / Mountain Lion from automatically saving application state.
         # If we don't do this, new windows will not display on 10.8 after finishLaunching
         # has been called.
         defaults = NSUserDefaults.standardUserDefaults()
         ignoreState = cocoapy.CFSTR("ApplePersistenceIgnoreState")
         if not defaults.objectForKey_(ignoreState):
             defaults.setBool_forKey_(True, ignoreState)
         self._finished_launching = False
Example #4
0
 def _create_font_descriptor(self, family_name, traits):
     # Create an attribute dictionary.
     attributes = c_void_p(
         cf.CFDictionaryCreateMutable(None, 0,
                                      cf.kCFTypeDictionaryKeyCallBacks,
                                      cf.kCFTypeDictionaryValueCallBacks))
     # Add family name to attributes.
     cfname = cocoapy.CFSTR(family_name)
     cf.CFDictionaryAddValue(attributes, cocoapy.kCTFontFamilyNameAttribute,
                             cfname)
     cf.CFRelease(cfname)
     # Construct a CFNumber to represent the traits.
     itraits = c_int32(traits)
     symTraits = c_void_p(
         cf.CFNumberCreate(None, cocoapy.kCFNumberSInt32Type,
                           byref(itraits)))
     if symTraits:
         # Construct a dictionary to hold the traits values.
         traitsDict = c_void_p(
             cf.CFDictionaryCreateMutable(
                 None, 0, cf.kCFTypeDictionaryKeyCallBacks,
                 cf.kCFTypeDictionaryValueCallBacks))
         if traitsDict:
             # Add CFNumber traits to traits dictionary.
             cf.CFDictionaryAddValue(traitsDict,
                                     cocoapy.kCTFontSymbolicTrait,
                                     symTraits)
             # Add traits dictionary to attributes.
             cf.CFDictionaryAddValue(attributes,
                                     cocoapy.kCTFontTraitsAttribute,
                                     traitsDict)
             cf.CFRelease(traitsDict)
         cf.CFRelease(symTraits)
     # Create font descriptor with attributes.
     descriptor = c_void_p(
         ct.CTFontDescriptorCreateWithAttributes(attributes))
     cf.CFRelease(attributes)
     return descriptor
Example #5
0
    def render(self, text):
        # Using CTLineDraw seems to be the only way to make sure that the text
        # is drawn with the specified font when that font is a graphics font loaded from
        # memory.  For whatever reason, [NSAttributedString drawAtPoint:] ignores
        # the graphics font if it not registered with the font manager.
        # So we just use CTLineDraw for both graphics fonts and installed fonts.

        ctFont = self.font.ctFont

        # Create an attributed string using text and font.
        attributes = c_void_p(
            cf.CFDictionaryCreateMutable(None, 1,
                                         cf.kCFTypeDictionaryKeyCallBacks,
                                         cf.kCFTypeDictionaryValueCallBacks))
        cf.CFDictionaryAddValue(attributes, cocoapy.kCTFontAttributeName,
                                ctFont)
        string = c_void_p(
            cf.CFAttributedStringCreate(None, cocoapy.CFSTR(text), attributes))

        # Create a CTLine object to render the string.
        line = c_void_p(ct.CTLineCreateWithAttributedString(string))
        cf.CFRelease(string)
        cf.CFRelease(attributes)

        # Get a bounding rectangle for glyphs in string.
        count = len(text)
        chars = (cocoapy.UniChar * count)(*list(map(ord, str(text))))
        glyphs = (cocoapy.CGGlyph * count)()
        ct.CTFontGetGlyphsForCharacters(ctFont, chars, glyphs, count)
        rect = ct.CTFontGetBoundingRectsForGlyphs(ctFont, 0, glyphs, None,
                                                  count)

        # Get advance for all glyphs in string.
        advance = ct.CTFontGetAdvancesForGlyphs(ctFont, 0, glyphs, None, count)

        # Set image parameters:
        # We add 2 pixels to the bitmap width and height so that there will be a 1-pixel border
        # around the glyph image when it is placed in the texture atlas.  This prevents
        # weird artifacts from showing up around the edges of the rendered glyph textures.
        # We adjust the baseline and lsb of the glyph by 1 pixel accordingly.
        width = max(int(math.ceil(rect.size.width) + 2), 1)
        height = max(int(math.ceil(rect.size.height) + 2), 1)
        baseline = -int(math.floor(rect.origin.y)) + 1
        lsb = int(math.floor(rect.origin.x)) - 1
        advance = int(round(advance))

        # Create bitmap context.
        bitsPerComponent = 8
        bytesPerRow = 4 * width
        colorSpace = c_void_p(quartz.CGColorSpaceCreateDeviceRGB())
        bitmap = c_void_p(
            quartz.CGBitmapContextCreate(
                None, width, height, bitsPerComponent, bytesPerRow, colorSpace,
                cocoapy.kCGImageAlphaPremultipliedLast))

        # Draw text to bitmap context.
        quartz.CGContextSetShouldAntialias(bitmap, True)
        quartz.CGContextSetTextPosition(bitmap, -lsb, baseline)
        ct.CTLineDraw(line, bitmap)
        cf.CFRelease(line)

        # Create an image to get the data out.
        imageRef = c_void_p(quartz.CGBitmapContextCreateImage(bitmap))

        bytesPerRow = quartz.CGImageGetBytesPerRow(imageRef)
        dataProvider = c_void_p(quartz.CGImageGetDataProvider(imageRef))
        imageData = c_void_p(quartz.CGDataProviderCopyData(dataProvider))
        buffersize = cf.CFDataGetLength(imageData)
        buffer = (c_byte * buffersize)()
        byteRange = cocoapy.CFRange(0, buffersize)
        cf.CFDataGetBytes(imageData, byteRange, buffer)

        quartz.CGImageRelease(imageRef)
        quartz.CGDataProviderRelease(imageData)
        cf.CFRelease(bitmap)
        cf.CFRelease(colorSpace)

        glyph_image = pyglet.image.ImageData(width, height, 'RGBA', buffer,
                                             bytesPerRow)

        glyph = self.font.create_glyph(glyph_image)
        glyph.set_bearings(baseline, lsb, advance)
        t = list(glyph.tex_coords)
        glyph.tex_coords = t[9:12] + t[6:9] + t[3:6] + t[:3]

        return glyph