Split X11.subproj into X11.backend and Linux.subproj (FreeType, fontconfig)

Also, drop unused NSOpenGLDrawable_X11, O2Context_cairo and O2Surface_cairo.
This commit is contained in:
Sergey Bugaev 2018-09-17 22:06:34 +03:00
parent 9622fe5236
commit ba12e65f5a
35 changed files with 22 additions and 1278 deletions

View File

@ -51,11 +51,13 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/NSTextView.subproj
${CMAKE_CURRENT_SOURCE_DIR}/NSEvent.subproj
${CMAKE_CURRENT_SOURCE_DIR}/NSColor.subproj
${CMAKE_CURRENT_SOURCE_DIR}/X11.subproj
${CMAKE_CURRENT_SOURCE_DIR}/RTF.subproj
${CMAKE_CURRENT_SOURCE_DIR}/NSToolbar.subproj
${CMAKE_CURRENT_SOURCE_DIR}/NSDrawer.subproj
${CMAKE_CURRENT_SOURCE_DIR}/Linux.subproj
${CMAKE_CURRENT_SOURCE_DIR}/X11.backend
${X11_INCLUDE_DIRS}
${FREETYPE_INCLUDE_DIRS}
${OPENGL_INCLUDE_DIRS}
@ -298,18 +300,14 @@ set(AppKit_sources
NSInterfacePart/NSGraphicsStyle.m
NSInterfacePart/NSInterfacePart.m
# X11.subproj/O2FontState_cairo.m
X11.subproj/X11Event.m
# X11.subproj/O2Surface_cairo.m
X11.subproj/X11Window.m
X11.subproj/X11SubWindow.m
X11.subproj/KTFont_FT.m
# O2Font_FT.m is built in Onyx2D
# CGLContext.m no longer used
# X11.subproj/NSOpenGLDrawable_X11.m
# X11.subproj/O2Context_cairo.m
X11.subproj/X11Display.m
X11.subproj/O2Context_builtin_FT.m
X11.backend/X11Display.m
X11.backend/X11Window.m
X11.backend/X11SubWindow.m
X11.backend/X11Event.m
Linux.subproj/KTFont_FT.m
Linux.subproj/O2Context_builtin_FT.m
# Linux.subproj/O2Font_FT.m is built in Onyx2D
NSImageView.m
NSActionCell.m

View File

@ -1 +1 @@
X11.subproj/KTFont_FT.h
Linux.subproj/KTFont_FT.h

View File

@ -1 +0,0 @@
X11.subproj/NSOpenGLDrawable_X11.h

View File

@ -1 +1 @@
X11.subproj/O2Context_builtin_FT.h
Linux.subproj/O2Context_builtin_FT.h

View File

@ -1 +0,0 @@
X11.subproj/O2Context_cairo.h

View File

@ -1 +0,0 @@
X11.subproj/O2FontState_cairo.h

View File

@ -1 +1 @@
X11.subproj/O2Font_FT.h
Linux.subproj/O2Font_FT.h

View File

@ -1 +0,0 @@
X11.subproj/O2Surface_cairo.h

View File

@ -1,6 +1,6 @@
#import "X11SubWindow.h"
#import <AppKit/X11Window.h>
#import <AppKit/X11Display.h>
#import "X11Window.h"
#import "X11Display.h"
@implementation X11SubWindow

View File

@ -6,17 +6,18 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#import <AppKit/X11Window.h>
#import <AppKit/NSWindow.h>
#import <AppKit/NSPanel.h>
#import <AppKit/X11Display.h>
#import <AppKit/NSRaise.h>
#import <X11/Xutil.h>
#import <QuartzCore/CAWindowOpenGLContext.h>
#import <Foundation/NSException.h>
#import <Onyx2D/O2Surface.h>
#import "O2Context_builtin_FT.h"
#import <X11/Xutil.h>
#import "X11Display.h"
#import "X11Window.h"
#import "X11SubWindow.h"
#import <QuartzCore/CAWindowOpenGLContext.h>
void CGNativeBorderFrameWidthsForStyle(NSUInteger styleMask,CGFloat *top,CGFloat *left,CGFloat *bottom,CGFloat *right) {
*top=0;

View File

@ -1,451 +0,0 @@
#import <OpenGL/OpenGL.h>
#import <Foundation/NSString.h>
#import "X11Display.h"
#import "X11Window.h"
#import <Foundation/NSRaise.h>
#import <X11/X.h>
#import <X11/Xlib.h>
#import <GL/gl.h>
#import <GL/glx.h>
#import <GL/glext.h>
#import <pthread.h>
struct _CGLContextObj {
GLuint retainCount;
pthread_mutex_t lock;
Display *display;
XVisualInfo *visualInfo;
Window window;
GLXContext glc;
int x,y,w,h;
GLint opacity;
int windowNumber;
};
struct _CGLPixelFormatObj {
GLuint retainCount;
CGLPixelFormatAttribute *attributes;
};
static pthread_key_t cglContextKey;
static void make_key(){
pthread_key_create(&cglContextKey,NULL);
}
static pthread_key_t cglThreadKey(){
static pthread_once_t key_once=PTHREAD_ONCE_INIT;
pthread_once(&key_once,make_key);
return cglContextKey;
}
CGLContextObj CGLGetCurrentContext(void) {
CGLContextObj result=pthread_getspecific(cglThreadKey());
return result;
}
CGLError CGLSetCurrentContext(CGLContextObj context) {
pthread_setspecific(cglThreadKey(), context);
if(context==NULL)
;//glXMakeCurrent(NULL, None, NULL); // FIXME: NULL for display? probably crashes
else
glXMakeCurrent(context->display, context->window, context->glc);
return kCGLNoError;
}
static inline bool attributeHasArgument(CGLPixelFormatAttribute attribute){
switch(attribute){
case kCGLPFAAuxBuffers:
case kCGLPFAColorSize:
case kCGLPFAAlphaSize:
case kCGLPFADepthSize:
case kCGLPFAStencilSize:
case kCGLPFAAccumSize:
case kCGLPFARendererID:
case kCGLPFADisplayMask:
return TRUE;
default:
return FALSE;
}
}
static GLint *addAttribute(GLint *attribList,int *capacity,int *count,GLint value){
if(*count>=*capacity){
*capacity*=2;
attribList=realloc(attribList,*capacity*sizeof(GLint));
}
attribList[(*count)++]=value;
return attribList;
}
static GLint *attributesFromPixelFormat(CGLPixelFormatObj pixelFormat){
int resultCapacity=8,resultCount=0;
GLint *result=malloc(resultCapacity*sizeof(GLint));
int i,virtualScreen=0;
result=addAttribute(result,&resultCapacity,&resultCount,GLX_RGBA);
for(i=0;pixelFormat->attributes[i]!=0;i++){
CGLPixelFormatAttribute attribute=pixelFormat->attributes[i];
if(attributeHasArgument(pixelFormat->attributes[i]))
i++;
switch(attribute){
case kCGLPFAColorSize:
result=addAttribute(result,&resultCapacity,&resultCount,GLX_RED_SIZE);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]/3);
result=addAttribute(result,&resultCapacity,&resultCount,GLX_GREEN_SIZE);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]/3);
result=addAttribute(result,&resultCapacity,&resultCount,GLX_BLUE_SIZE);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]/3);
break;
case kCGLPFAAlphaSize:
result=addAttribute(result,&resultCapacity,&resultCount,GLX_ALPHA_SIZE);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]);
break;
case kCGLPFAAccumSize:
result=addAttribute(result,&resultCapacity,&resultCount,GLX_ACCUM_RED_SIZE);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]/4);
result=addAttribute(result,&resultCapacity,&resultCount,GLX_ACCUM_GREEN_SIZE);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]/4);
result=addAttribute(result,&resultCapacity,&resultCount,GLX_ACCUM_BLUE_SIZE);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]/4);
result=addAttribute(result,&resultCapacity,&resultCount,GLX_ACCUM_ALPHA_SIZE);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]/4);
break;
case kCGLPFADepthSize:
result=addAttribute(result,&resultCapacity,&resultCount,GLX_DEPTH_SIZE);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]);
break;
case kCGLPFAStencilSize:
result=addAttribute(result,&resultCapacity,&resultCount,GLX_STENCIL_SIZE);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]);
break;
case kCGLPFAAuxBuffers:
result=addAttribute(result,&resultCapacity,&resultCount,GLX_AUX_BUFFERS);
result=addAttribute(result,&resultCapacity,&resultCount,pixelFormat->attributes[i]);
break;
}
}
result=addAttribute(result,&resultCapacity,&resultCount,None);
return result;
}
CGLError CGLCreateContextForWindow(CGLPixelFormatObj pixelFormat,CGLContextObj share,CGLContextObj *resultp,Display *display,XVisualInfo *visualInfo,Window window) {
CGLContextObj context=malloc(sizeof(struct _CGLContextObj));
context->retainCount=1;
pthread_mutex_init(&(context->lock),NULL);
context->display=display;
context->visualInfo=visualInfo;
context->window=window;
context->glc=glXCreateContext(context->display,context->visualInfo,NULL,GL_TRUE);
context->x=0;
context->y=0;
context->w=1;
context->h=1;
context->opacity=1;
context->windowNumber=0;
*resultp=context;
return kCGLNoError;
}
CGLError CGLCreateContext(CGLPixelFormatObj pixelFormat,CGLContextObj share,CGLContextObj *resultp) {
Display *display=[(X11Display*)[NSDisplay currentDisplay] display];
XVisualInfo*visualInfo;
Window window;
GLint *attribList=attributesFromPixelFormat(pixelFormat);
int screen=DefaultScreen(display);
if((visualInfo=glXChooseVisual(display,screen,attribList))==NULL){
NSLog(@"glXChooseVisual failed");
return kCGLBadDisplay;
}
if(visualInfo==NULL)
return kCGLBadDisplay;
Colormap cmap = XCreateColormap(display, RootWindow(display, visualInfo->screen), visualInfo->visual, AllocNone);
if(cmap<0){
NSLog(@"XCreateColormap failed");
return kCGLBadDisplay;
}
XSetWindowAttributes xattr={0};
xattr.colormap=cmap;
xattr.border_pixel = 0;
xattr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
Window parent=RootWindow(display, visualInfo->screen);
window = XCreateWindow(display,parent, 0, 0, 1,1, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBorderPixel | CWColormap | CWEventMask, &xattr);
//XSetWindowBackgroundPixmap(display, window, None);
//[X11Window removeDecorationForWindow:window onDisplay:display];
XMapWindow(display, window);
return CGLCreateContextForWindow(pixelFormat,share,resultp,display,visualInfo,window);
}
CGLContextObj CGLRetainContext(CGLContextObj context) {
if(context==NULL)
return NULL;
context->retainCount++;
return context;
}
void CGLReleaseContext(CGLContextObj context) {
if(context==NULL)
return;
context->retainCount--;
if(context->retainCount==0){
if(CGLGetCurrentContext()==context)
CGLSetCurrentContext(NULL);
if(context->window)
XDestroyWindow(context->display, context->window);
pthread_mutex_destroy(&(context->lock));
glXDestroyContext(context->display, context->glc);
free(context);
}
}
GLuint CGLGetContextRetainCount(CGLContextObj context) {
if(context==NULL)
return 0;
return context->retainCount;
}
CGLError CGLDestroyContext(CGLContextObj context) {
CGLReleaseContext(context);
return kCGLNoError;
}
CGLError CGLLockContext(CGLContextObj context) {
pthread_mutex_lock(&(context->lock));
return kCGLNoError;
}
CGLError CGLUnlockContext(CGLContextObj context) {
pthread_mutex_unlock(&(context->lock));
return kCGLNoError;
}
static bool usesChildWindow(CGLContextObj context){
return (context->opacity!=0)?TRUE:FALSE;
}
static void adjustFrameInParent(CGLContextObj context,X11Window *parentWindow,GLint *x,GLint *y,GLint *w,GLint *h){
if(parentWindow!=nil){
CGFloat top,left,bottom,right;
CGNativeBorderFrameWidthsForStyle([parentWindow styleMask],&top,&left,&bottom,&right);
*y=[parentWindow frame].size.height-(*y+*h);
*y-=top;
*x-=left;
}
}
static void adjustInParentForSurfaceOpacity(CGLContextObj context){
GLint x=context->x;
GLint y=context->y;
GLint w=context->w;
GLint h=context->h;
if(usesChildWindow(context)){
X11Window *parentWindow=[X11Window windowWithWindowNumber:context->windowNumber];
Window parentHandle=[parentWindow windowHandle];
adjustFrameInParent(context,parentWindow,&x,&y,&w,&h);
XReparentWindow(context->display, parentHandle, context->window, x, y);
}
XMoveResizeWindow(context->display,context->window, x, y, w, h);
}
CGLError CGLSetParameter(CGLContextObj context,CGLContextParameter parameter,const GLint *value) {
switch(parameter){
case kCGLCPSurfaceFrame:;
context->x=value[0];
context->y=value[1];
context->w=value[2];
context->h=value[3];
adjustInParentForSurfaceOpacity(context);
break;
case kCGLCPSurfaceOpacity:
context->opacity=*value;
adjustInParentForSurfaceOpacity(context);
break;
case kCGLCPWindowNumber:
context->windowNumber=*value;
adjustInParentForSurfaceOpacity(context);
break;
default:
NSLog(@"CGLSetParameter unimplemented for parameter %i",parameter);
break;
}
return kCGLNoError;
}
CGLError CGLGetParameter(CGLContextObj context,CGLContextParameter parameter,GLint *value) {
switch(parameter){
case kCGLCPSurfaceOpacity:
*value=context->opacity;
break;
default:
break;
}
return kCGLNoError;
}
CGLError CGLFlushDrawable(CGLContextObj context) {
glXSwapBuffers(context->display,context->window);
return kCGLNoError;
}
static int attributesCount(const CGLPixelFormatAttribute *attributes){
int result;
for(result=0;attributes[result]!=0;result++)
if(attributeHasArgument(attributes[result]))
result++;
return result;
}
CGLError CGLChoosePixelFormat(const CGLPixelFormatAttribute *attributes,CGLPixelFormatObj *pixelFormatp,GLint *numberOfScreensp) {
CGLPixelFormatObj result=malloc(sizeof(struct _CGLPixelFormatObj));
int i,count=attributesCount(attributes);
result->retainCount=1;
result->attributes=malloc(sizeof(CGLPixelFormatAttribute)*count);
for(i=0;i<count;i++)
result->attributes[i]=attributes[i];
*pixelFormatp=result;
*numberOfScreensp=1;
return kCGLNoError;
}
CGLPixelFormatObj CGLRetainPixelFormat(CGLPixelFormatObj pixelFormat) {
if(pixelFormat==NULL)
return NULL;
pixelFormat->retainCount++;
return pixelFormat;
}
void CGLReleasePixelFormat(CGLPixelFormatObj pixelFormat) {
if(pixelFormat==NULL)
return;
pixelFormat->retainCount--;
if(pixelFormat->retainCount==0){
free(pixelFormat->attributes);
free(pixelFormat);
}
}
CGLError CGLDestroyPixelFormat(CGLPixelFormatObj pixelFormat) {
CGLReleasePixelFormat(pixelFormat);
return kCGLNoError;
}
GLuint CGLGetPixelFormatRetainCount(CGLPixelFormatObj pixelFormat) {
return pixelFormat->retainCount;
}
CGLError CGLDescribePixelFormat(CGLPixelFormatObj pixelFormat,GLint screenNumber,CGLPixelFormatAttribute attribute,GLint *valuesp) {
int i;
for(i=0;pixelFormat->attributes[i]!=0;i++){
bool hasArgument=attributeHasArgument(pixelFormat->attributes[i]);
if(pixelFormat->attributes[i]==attribute){
if(hasArgument)
*valuesp=pixelFormat->attributes[i+1];
else
*valuesp=1;
return kCGLNoError;
}
if(hasArgument)
i++;
}
*valuesp=0;
return kCGLNoError;
}
void CGLBufferData(GLenum target,GLsizeiptr size,const GLvoid *data,GLenum usage) {
glBufferData(target,size,data,usage);
}
void CGLGenBuffers(GLsizei n,GLuint *buffers) {
glGenBuffers(n,buffers);
}
void CGLDeleteBuffers(GLsizei n,const GLuint *buffers) {
glDeleteBuffers(n,buffers);
}
void CGLBindBuffer(GLenum target,GLuint buffer) {
glBindBuffer(target,buffer);
}
void *CGLMapBuffer(GLenum target,GLenum access) {
return glMapBuffer(target,access);
}
CGL_EXPORT GLboolean CGLUnmapBuffer(GLenum target) {
return glUnmapBuffer(target);
}
void CGLBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid *data) {
glBufferSubData(target,offset,size,data);
}

View File

@ -1,26 +0,0 @@
//
// NSOpenGLDrawable_X11.h
// AppKit
//
// Created by Johannes Fortmann on 02.01.09.
// Copyright 2009 -. All rights reserved.
//
#import <AppKit/NSOpenGLDrawable.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
@class NSView, NSOpenGLPixelFormat;
@interface NSOpenGLDrawable_X11 : NSOpenGLDrawable {
NSOpenGLPixelFormat *_format;
Display *_display;
XVisualInfo *_visualInfo;
Window _window;
Window _lastParent;
}
@end

View File

@ -1,154 +0,0 @@
//
// NSOpenGLDrawable_X11.m
// AppKit
//
// Created by Johannes Fortmann on 02.01.09.
// Copyright 2009 -. All rights reserved.
//
#import <AppKit/NSOpenGLDrawable_X11.h>
#import <AppKit/X11Display.h>
#import <AppKit/X11Window.h>
#import <AppKit/NSWindow-Private.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#import <OpenGL/OpenGL.h>
#include <GL/glx.h>
// defined in AppKit/X11.subproj/CGLContext.m
CGLError CGLCreateContextForWindow(CGLPixelFormatObj pixelFormat,CGLContextObj share,CGLContextObj *resultp,Display *display,XVisualInfo *visualInfo,Window window);
@implementation NSOpenGLDrawable(X11)
+allocWithZone:(NSZone *)zone {
return NSAllocateObject([NSOpenGLDrawable_X11 class],0,NULL);
}
@end
@implementation NSOpenGLDrawable_X11
-initWithPixelFormat:(NSOpenGLPixelFormat *)pixelFormat view:(NSView *)view {
if(self = [super init]) {
_format=[pixelFormat retain];
_display=[(X11Display*)[NSDisplay currentDisplay] display];
GLint att[] = {
GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 4,
None
};
int screen = DefaultScreen(_display);
if((_visualInfo=glXChooseVisual(_display,screen,att))==NULL){
NSLog(@"glXChooseVisual failed");
[self dealloc];
return nil;;
}
Colormap cmap = XCreateColormap(_display, RootWindow(_display, _visualInfo->screen), _visualInfo->visual, AllocNone);
if(cmap<0){
NSLog(@"XCreateColormap failed");
[self dealloc];
return nil;
}
XSetWindowAttributes xattr;
bzero(&xattr,sizeof(xattr));
xattr.colormap=cmap;
xattr.border_pixel = 0;
xattr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
NSRect frame=[view frame];
Window parent=[(X11Window*)[[view window] platformWindow] drawable];
if(parent==0)
parent=RootWindow(_display, _visualInfo->screen);
_window = XCreateWindow(_display,parent, frame.origin.x, frame.origin.y, frame.size.width,frame.size.height, 0, _visualInfo->depth, InputOutput, _visualInfo->visual, CWBorderPixel | CWColormap | CWEventMask, &xattr);
// XSetWindowBackgroundPixmap(_display, _window, None);
// [X11Window removeDecorationForWindow:_window onDisplay:_display];
XMapWindow(_display, _window);
}
return self;
}
-(void)dealloc {
if(_window)
XDestroyWindow(_display, _window);
[_format release];
[super dealloc];
}
-(CGLContextObj)createGLContext {
CGLContextObj result=NULL;
CGLError error = CGLCreateContextForWindow(
NULL, /* CGLPixelFormatObj pixelFormat, unused */
NULL, /* CGLContextObj share, unused */
&result,
_display,
_visualInfo,
_window
);
if(error != kCGLNoError)
NSLog(@"CGLCreateContext failed with %d in %s %d",error,__FILE__,__LINE__);
return result;
}
-(void)invalidate {
}
-(void)updateWithView:(NSView *)view {
NSRect frame=[view frame];
frame=[[view superview] convertRect:frame toView:nil];
X11Window *wnd=(X11Window*)[[view window] platformWindow];
NSRect wndFrame=[wnd frame];
frame.origin.y=wndFrame.size.height-(frame.origin.y+frame.size.height);
XMoveResizeWindow(_display, _window, frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
Window viewWindow=[(X11Window*)[[view window] platformWindow] drawable];
if(_lastParent!=viewWindow) {
XReparentWindow(_display, _window, viewWindow, frame.origin.x, frame.origin.y);
_lastParent=viewWindow;
}
}
-(void)makeCurrentWithGLContext:(CGLContextObj)glContext {
CGLError error;
if((error=CGLSetCurrentContext(glContext))!=kCGLNoError)
NSLog(@"CGLSetCurrentContext failed with %d in %s %d",error,__FILE__,__LINE__);
}
-(void)clearCurrentWithGLContext:(CGLContextObj)glContext {
CGLError error;
if((error=CGLSetCurrentContext(NULL))!=kCGLNoError)
NSLog(@"CGLSetCurrentContext failed with %d in %s %d",error,__FILE__,__LINE__);
}
-(void)swapBuffers {
glXSwapBuffers(_display, _window);
}
@end

View File

@ -1,23 +0,0 @@
/* Copyright (c) 2008 Johannes Fortmann
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#import <Onyx2D/O2Context.h>
#import <cairo.h>
#import <X11/Xlib.h>
#import <cairo-xlib.h>
#import <AppKit/X11Window.h>
@interface O2Context_cairo : O2Context {
cairo_t *_context;
cairo_surface_t *_surface;
}
- (NSSize)size;
- (void)drawBackingContext:(O2Context *)other size:(NSSize)size;
@end

View File

@ -1,490 +0,0 @@
/* Copyright (c) 2008 Johannes Fortmann
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#import "O2Context_cairo.h"
#import <AppKit/X11Display.h>
#import <Onyx2D/O2MutablePath.h>
#import <Onyx2D/O2Color.h>
#import <Foundation/NSException.h>
#import <Onyx2D/O2GraphicsState.h>
#import <Onyx2D/O2ClipState.h>
#import <Onyx2D/O2ClipPhase.h>
#import <AppKit/KTFont_FT.h>
#import <Onyx2D/O2ColorSpace.h>
#import <Onyx2D/O2Surface.h>
#import <Foundation/NSException.h>
#import <cairo/cairo-ft.h>
#import <cairo/cairo.h>
#import "O2FontState_cairo.h"
#import "O2Surface_cairo.h"
#import "O2Context_builtin_FT.h"
@implementation O2Context_cairo
+(BOOL)canInitWithWindow:(CGWindow *)window {
return YES;
}
+(BOOL)canInitBackingWithContext:(O2Context *)context deviceDictionary:(NSDictionary *)deviceDictionary {
NSString *name=[deviceDictionary objectForKey:@"O2Context"];
if(name==nil || [name isEqual:@"cairo"])
return YES;
return NO;
}
-initWithSize:(O2Size)size window:(CGWindow *)cgWindow {
X11Window *window=(X11Window *)cgWindow;
O2Rect frame=[window frame];
O2GState *initialState=[[[O2GState alloc] initWithDeviceTransform:O2AffineTransformIdentity] autorelease];
if(self=[super initWithGraphicsState:initialState]){
Display *dpy=[(X11Display*)[NSDisplay currentDisplay] display];
_surface = cairo_xlib_surface_create(dpy, [window drawable], [window visual], frame.size.width, frame.size.height);
_context = cairo_create(_surface);
}
return self;
}
-initWithSize:(O2Size)size context:(O2Context *)context {
O2GState *initialState=[[[O2GState alloc] initWithDeviceTransform:O2AffineTransformIdentity] autorelease];
if(self=[super initWithGraphicsState:initialState]){
_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size.width, size.height);
_context = cairo_create(_surface);
}
return self;
}
-(void)dealloc {
cairo_surface_destroy(_surface);
cairo_destroy(_context);
[super dealloc];
}
-(O2Surface *)createSurfaceWithWidth:(size_t)width height:(size_t)height {
return [[O2Surface_cairo alloc] initWithWidth:width height:height compatibleWithContext:self];
}
-(void)setCurrentColor:(O2Color*)color
{
const CGFloat *c=O2ColorGetComponents(color);
int count=O2ColorGetNumberOfComponents(color);
switch(count)
{
case 1:
cairo_set_source_rgba(_context,
c[0],
c[0],
c[0],
1.0);
break;
case 2:
cairo_set_source_rgba(_context,
c[0],
c[0],
c[0],
c[1]);
break;
case 3:
cairo_set_source_rgba(_context,
c[0],
c[1],
c[2],
1.0);
break;
case 4:
cairo_set_source_rgba(_context,
c[0],
c[1],
c[2],
c[3]);
break;
default:
NSLog(@"color with %i components", count);
cairo_set_source_rgba(_context,
1.0,
0.0,
1.0,
1.0);
break;
}
}
-(void)appendCTM
{
O2AffineTransform ctm=O2ContextGetCTM(self);
cairo_matrix_t matrix={ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty};
cairo_transform(_context,&matrix);
}
-(void)synchronizeFontCTM
{
O2AffineTransform ctm = O2ContextGetTextMatrix(self);
O2Float size = O2GStatePointSize(O2ContextCurrentGState(self));
ctm = O2AffineTransformScale(ctm, size, -size);
cairo_matrix_t matrix={ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty};
cairo_set_font_matrix(_context, &matrix);
}
-(void)appendFlip
{
cairo_matrix_t matrix={1, 0, 0, -1, 0, [self size].height};
cairo_transform(_context,&matrix);
}
-(void)synchronizeLineAttributes
{
O2GState *gState=O2ContextCurrentGState(self);
int i;
cairo_set_line_width(_context, gState->_lineWidth);
cairo_set_line_cap(_context, gState->_lineCap);
cairo_set_line_join(_context, gState->_lineJoin);
cairo_set_miter_limit(_context, gState->_miterLimit);
double dashLengths[gState->_dashLengthsCount];
double totalLength=0.0;
for(i=0; i<gState->_dashLengthsCount; i++)
{
dashLengths[i]=(double)gState->_dashLengths[i];
totalLength=(double)gState->_dashLengths[i];
}
cairo_set_dash (_context, dashLengths, gState->_dashLengthsCount, gState->_dashPhase/totalLength);
}
-(void)setCurrentPath:(O2Path*)path
{
unsigned opCount=O2PathNumberOfElements(path);
const unsigned char *operators=O2PathElements(path);
unsigned pointCount=O2PathNumberOfPoints(path);
const NSPoint *points=O2PathPoints(path);
unsigned i,pointIndex;
cairo_identity_matrix(_context);
cairo_new_path(_context);
[self appendFlip];
pointIndex=0;
for(i=0;i<opCount;i++){
switch(operators[i]){
case kCGPathElementMoveToPoint:{
NSPoint point=points[pointIndex++];
cairo_move_to(_context,point.x,point.y);
}
break;
case kCGPathElementAddLineToPoint:{
NSPoint point=points[pointIndex++];
cairo_line_to(_context,point.x,point.y);
}
break;
case kCGPathElementAddCurveToPoint:{
NSPoint cp1=points[pointIndex++];
NSPoint cp2=points[pointIndex++];
NSPoint end=points[pointIndex++];
cairo_curve_to(_context,cp1.x,cp1.y,
cp2.x,cp2.y,
end.x,end.y);
}
break;
case kCGPathElementAddQuadCurveToPoint:{
NSPoint cp1=points[pointIndex++];
NSPoint end=points[pointIndex++];
cairo_curve_to(_context,cp1.x,cp1.y,
cp1.x,cp1.y,
end.x,end.y);
}
break;
case kCGPathElementCloseSubpath:
cairo_close_path(_context);
break;
}
}
}
-(void)clipToState:(O2ClipState *)clipState {
NSArray *phases=[O2GStateClipState(O2ContextCurrentGState(self)) clipPhases];
int i,count=[phases count];
cairo_reset_clip(_context);
for(i=0;i<count;i++){
O2ClipPhase *phase=[phases objectAtIndex:i];
switch(O2ClipPhasePhaseType(phase)){
case O2ClipPhaseNonZeroPath:;
O2Path *path=O2ClipPhaseObject(phase);
[self setCurrentPath:path];
cairo_set_fill_rule(_context, CAIRO_FILL_RULE_WINDING);
cairo_clip(_context);
break;
case O2ClipPhaseEOPath:{
O2Path *path=O2ClipPhaseObject(phase);
// not handled
}
break;
case O2ClipPhaseMask:
break;
}
}
}
-(void)drawPath:(O2PathDrawingMode)mode
{
[self setCurrentPath:(O2Path*)_path];
switch(mode)
{
case kCGPathStroke:
[self setCurrentColor:O2ContextStrokeColor(self)];
[self synchronizeLineAttributes];
cairo_stroke_preserve(_context);
break;
case kCGPathFill:
[self setCurrentColor:O2ContextFillColor(self)];
cairo_set_fill_rule(_context, CAIRO_FILL_RULE_WINDING);
cairo_fill_preserve(_context);
break;
case kCGPathEOFill:
[self setCurrentColor:O2ContextFillColor(self)];
cairo_set_fill_rule(_context, CAIRO_FILL_RULE_EVEN_ODD);
cairo_fill_preserve(_context);
break;
case kCGPathFillStroke:
[self setCurrentColor:O2ContextFillColor(self)];
cairo_set_fill_rule(_context, CAIRO_FILL_RULE_WINDING);
cairo_fill_preserve(_context);
[self setCurrentColor:O2ContextStrokeColor(self)];
[self synchronizeLineAttributes];
cairo_stroke_preserve(_context);
break;
case kCGPathEOFillStroke:
[self setCurrentColor:O2ContextFillColor(self)];
cairo_set_fill_rule(_context, CAIRO_FILL_RULE_EVEN_ODD);
cairo_fill_preserve(_context);
[self setCurrentColor:O2ContextStrokeColor(self)];
[self synchronizeLineAttributes];
cairo_stroke_preserve(_context);
break;
}
cairo_new_path(_context);
O2PathReset(_path);
}
-(BOOL)resizeWithNewSize:(O2Size)size {
switch(cairo_surface_get_type(_surface)){
case CAIRO_SURFACE_TYPE_XLIB:
// if(_context!=NULL)
// cairo_destroy(_context);
cairo_xlib_surface_set_size(_surface, size.width, size.height);
// _context = cairo_create(_surface);
return YES;
default:
return NO;
}
}
-(NSSize)size {
switch(cairo_surface_get_type(_surface))
{
case CAIRO_SURFACE_TYPE_XLIB:
return NSMakeSize(cairo_xlib_surface_get_width(_surface), cairo_xlib_surface_get_height(_surface));
case CAIRO_SURFACE_TYPE_IMAGE:
return NSMakeSize(cairo_image_surface_get_width(_surface), cairo_image_surface_get_height(_surface));
default:
return NSZeroSize;
}
}
-(void)drawShading:(O2Shading *)shading {
if([shading isAxial]) {
cairo_pattern_t *pat;
pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0);
cairo_pattern_destroy(pat);
}
}
-(void)drawImage:(O2Image *)image inRect:(O2Rect)rect {
cairo_surface_t *surface=NULL;
if([image isKindOfClass:[O2Surface_cairo class]])
surface=cairo_surface_reference([(O2Surface_cairo *)image cairo_surface]);
else {
int width=O2ImageGetWidth(image);
int height=O2ImageGetHeight(image);
surface=cairo_image_surface_create(CAIRO_FORMAT_ARGB32,width,height);
unsigned char *data=cairo_image_surface_get_data(surface);
int bytesPerRow=cairo_image_surface_get_stride(surface);
int i;
for(i=0; i<height; i++) {
image->_read_argb8u(image, 0, i, (O2argb8u *)(data+i*bytesPerRow), width);
}
}
cairo_identity_matrix(_context);
[self appendFlip];
[self appendCTM];
cairo_new_path(_context);
cairo_translate(_context, rect.origin.x, rect.origin.y);
cairo_rectangle(_context,0, 0, rect.size.width, rect.size.height);
cairo_clip(_context);
cairo_set_source_surface(_context,surface, 0.0, 0.0);
cairo_paint(_context);
cairo_surface_destroy(surface);
}
-(void)establishFontStateInDeviceIfDirty {
O2GState *gState=O2ContextCurrentGState(self);
if(gState->_fontIsDirty){
O2GStateClearFontIsDirty(gState);
O2Font_FT *cgFont=(O2Font_FT *)O2GStateFont(gState);
KTFont *fontState=[[O2FontState_cairo alloc] initWithFreeTypeFont:cgFont size:O2GStatePointSize(gState)];
[gState setFontState:fontState];
[fontState release];
}
}
-(void)showGlyphs:(const O2Glyph *)glyphs advances:(const O2Size *)advancesIn count:(NSUInteger)count {
// FIXME: use advancesIn if not NULL
[self establishFontStateInDeviceIfDirty];
O2GState *gState=O2ContextCurrentGState(self);
O2Font *font=O2GStateFont(gState);
O2FontState_cairo *fontState=[gState fontState];
cairo_font_face_t *face=[fontState cairo_font_face];
cairo_glyph_t *cg=alloca(sizeof(cairo_glyph_t)*count);
NSInteger i,advances[count];
O2Float unitsPerEm=O2FontGetUnitsPerEm(font);
O2FontGetGlyphAdvances(font,glyphs,count,advances);
O2Float x=0, y=0;
for(i=0; i<count; i++){
cg[i].x=x;
cg[i].y=y;
cg[i].index=glyphs[i];
x+=((CGFloat)advances[i]/(CGFloat)unitsPerEm)*gState->_pointSize;
}
cairo_set_font_face(_context, face);
cairo_set_font_size(_context, gState->_pointSize);
cairo_identity_matrix(_context);
[self appendFlip];
[self appendCTM];
[self synchronizeFontCTM];
[self setCurrentColor:O2ContextFillColor(self)];
cairo_move_to(_context, 0, 0);
cairo_show_glyphs(_context, cg, count);
}
-(void)flush {
cairo_surface_flush(_surface);
}
-(cairo_surface_t *)cairo_surface {
return _surface;
}
cairo_status_t writeToData(void *closure,
const unsigned char *data,
unsigned int length) {
id obj=(id)closure;
[obj appendBytes:data length:length];
return CAIRO_STATUS_SUCCESS;
}
-(void)drawBackingContext:(O2Context *)other size:(NSSize)size {
cairo_surface_t *otherSurface=NULL;
if([other isKindOfClass:[O2Context_cairo class]])
otherSurface=[(O2Context_cairo *)other cairo_surface];
else if([other isKindOfClass:[O2Context_builtin_FT class]]){
O2Surface *surface=[(O2Context_builtin_FT *)other surface];
if([surface isKindOfClass:[O2Surface_cairo class]])
otherSurface=[(O2Surface_cairo *)surface cairo_surface];
}
if(otherSurface==NULL){
NSLog(@"unable to draw backing context %@",other);
return;
}
if(size.width==0 || size.height==0)
return;
cairo_identity_matrix(_context);
cairo_reset_clip(_context);
cairo_rectangle(_context,0,0,size.width,size.height);
cairo_set_source_surface(_context, otherSurface, 0, 0);
cairo_paint(_context);
cairo_surface_flush(_surface);
}
@end

View File

@ -1,25 +0,0 @@
#import <Onyx2D/O2Geometry.h>
#ifdef DARLING
#define __linux__
#endif
#import <cairo/cairo-ft.h>
#ifdef DARLING
#undef __linux__
#endif
@class O2Font_FT;
@interface O2FontState_cairo : NSObject {
O2Font_FT *_font;
O2Float _size;
cairo_font_face_t *_cairo_font_face;
}
- initWithFreeTypeFont:(O2Font_FT *)font size:(O2Float)size;
- (cairo_font_face_t *)cairo_font_face;
@end

View File

@ -1,23 +0,0 @@
#import "O2FontState_cairo.h"
#import "O2Font_FT.h"
@implementation O2FontState_cairo
-initWithFreeTypeFont:(O2Font_FT *)font size:(O2Float)size {
_font=[font retain];
_size=size;
_cairo_font_face=cairo_ft_font_face_create_for_ft_face([font face],0);
return self;
}
-(void)dealloc {
[_font release];
cairo_font_face_destroy(_cairo_font_face);
[super dealloc];
}
-(cairo_font_face_t *)cairo_font_face {
return _cairo_font_face;
}
@end

View File

@ -1,21 +0,0 @@
/* Copyright (c) 2009 Christopher J. W. Lloyd
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#import <Onyx2D/O2Surface.h>
#import <cairo.h>
@class O2Context_cairo;
@interface O2Surface_cairo : O2Surface {
cairo_surface_t *_cairo_surface;
}
- initWithWidth:(size_t)width height:(size_t)height compatibleWithContext:(O2Context_cairo *)compatible;
- (cairo_surface_t *)cairo_surface;
@end

View File

@ -1,35 +0,0 @@
#import "O2Surface_cairo.h"
@implementation O2Surface_cairo
-initWithWidth:(size_t)width height:(size_t)height compatibleWithContext:(O2Context_cairo *)compatible {
O2ColorSpaceRef colorSpace=O2ColorSpaceCreateDeviceRGB();
if([super initWithBytes:NULL width:width height:height bitsPerComponent:8 bytesPerRow:0 colorSpace:colorSpace bitmapInfo:kO2ImageAlphaPremultipliedFirst|kO2BitmapByteOrder32Little]==nil){
O2ColorSpaceRelease(colorSpace);
[self dealloc];
return nil;
}
O2ColorSpaceRelease(colorSpace);
if((_cairo_surface=cairo_image_surface_create_for_data(_pixelBytes,CAIRO_FORMAT_ARGB32,width,height,_bytesPerRow))==NULL){
NSLog(@"%s %d cairo_image_surface_create_for_data failed",__FILE__,__LINE__);
[self dealloc];
return NULL;
}
return self;
}
-(void)dealloc {
cairo_surface_destroy(_cairo_surface);
[super dealloc];
}
-(cairo_surface_t *)cairo_surface {
return _cairo_surface;
}
@end

View File

@ -1 +0,0 @@
X11.subproj/X11Display.h

View File

@ -1 +0,0 @@
X11.subproj/X11Event.h

View File

@ -1 +0,0 @@
X11.subproj/X11Window.h

View File

@ -143,7 +143,7 @@ set(Onyx2D_sources
O2zlib.m
VGPath.m
../AppKit/X11.subproj/O2Font_FT.m
../AppKit/Linux.subproj/O2Font_FT.m
)
set_source_files_properties(${Onyx2D_sources} LANGUAGE C)