]> git.saurik.com Git - wxWidgets.git/blame - src/cocoa/dc.mm
adde wxSTC bakefile
[wxWidgets.git] / src / cocoa / dc.mm
CommitLineData
a24aff65 1/////////////////////////////////////////////////////////////////////////////
891d0563
DE
2// Name: src/cocoa/dc.mm
3// Purpose: wxDC
4// Author: David Elliott
a24aff65 5// Modified by:
891d0563 6// Created: 2003/04/01
a24aff65 7// RCS-ID: $Id$
891d0563
DE
8// Copyright: (c) 2003 David Elliott
9// Licence: wxWindows license
a24aff65
DE
10/////////////////////////////////////////////////////////////////////////////
11
a24aff65 12#include "wx/dc.h"
a24aff65
DE
13#include "wx/log.h"
14
891d0563
DE
15#import <AppKit/NSBezierPath.h>
16#import <AppKit/NSTextStorage.h>
17#import <AppKit/NSLayoutManager.h>
18#import <AppKit/NSTextContainer.h>
19#import <AppKit/NSGraphicsContext.h>
20#import <AppKit/NSAffineTransform.h>
21#import <AppKit/NSColor.h>
22#import <AppKit/NSTypeSetter.h>
23
a24aff65 24IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
891d0563
DE
25wxDC *wxDC::sm_focusedDC = NULL;
26WX_NSTextStorage wxDC::sm_cocoaNSTextStorage = nil;
27WX_NSLayoutManager wxDC::sm_cocoaNSLayoutManager = nil;
28WX_NSTextContainer wxDC::sm_cocoaNSTextContainer = nil;
29
30void wxDC::CocoaInitializeTextSystem()
31{
32 wxASSERT_MSG(!sm_cocoaNSTextStorage && !sm_cocoaNSLayoutManager && !sm_cocoaNSTextContainer,"Text system already initalized! BAD PROGRAMMER!");
33
34 sm_cocoaNSTextStorage = [[NSTextStorage alloc] init];
35
36 sm_cocoaNSLayoutManager = [[NSLayoutManager alloc] init];
37 [sm_cocoaNSTextStorage addLayoutManager:sm_cocoaNSLayoutManager];
38 // NSTextStorage retains NSLayoutManager, but so do we
39 // [sm_cocoaNSLayoutManager release]; [sm_cocoaNSLayoutManager retain];
40
41 // NOTE: initWithContainerSize is the designated initializer, but the
42 // Apple CircleView sample gets away with just calling init, which
43 // is all we really need for our purposes.
44 sm_cocoaNSTextContainer = [[NSTextContainer alloc] init];
45 [sm_cocoaNSLayoutManager addTextContainer:sm_cocoaNSTextContainer];
46 // NSLayoutManager retains NSTextContainer, but so do we
47 // [sm_cocoaNSTextContainer release]; [sm_cocoaNSTextContainer retain];
48}
49
50void wxDC::CocoaShutdownTextSystem()
51{
52 [sm_cocoaNSTextContainer release]; sm_cocoaNSTextContainer = nil;
53 [sm_cocoaNSLayoutManager release]; sm_cocoaNSLayoutManager = nil;
54 [sm_cocoaNSTextStorage release]; sm_cocoaNSTextStorage = nil;
55}
56
57wxDC::wxDC(void)
58{
59}
60
61wxDC::~wxDC(void)
62{
63}
64
65void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
66{
67 NSBezierPath *bezpath = [NSBezierPath bezierPathWithRect:NSMakeRect(x,y,width,height)];
68 [bezpath stroke];
69}
70
71void wxDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
72{
73 NSBezierPath *bezpath = [NSBezierPath bezierPath];
74 [bezpath moveToPoint:NSMakePoint(x1,y1)];
75 [bezpath lineToPoint:NSMakePoint(x2,y2)];
76 [bezpath stroke];
77}
78
79void wxDC::DoGetTextExtent(const wxString& text, wxCoord *x, wxCoord *y, wxCoord *descent, wxCoord *externalLeading, wxFont *theFont) const
80{
81// FIXME: Cache this so it can be used for DoDrawText
82 wxASSERT_MSG(sm_cocoaNSTextStorage && sm_cocoaNSLayoutManager && sm_cocoaNSTextContainer, "Text system has not been initialized. BAD PROGRAMMER!");
83 NSAttributedString *attributedString = [[NSAttributedString alloc]
84 initWithString:[NSString stringWithCString:text.c_str()]];
85 [sm_cocoaNSTextStorage setAttributedString:attributedString];
86 [attributedString release];
87
88 NSRange glyphRange = [sm_cocoaNSLayoutManager glyphRangeForTextContainer:sm_cocoaNSTextContainer];
89 NSRect usedRect = [sm_cocoaNSLayoutManager usedRectForTextContainer:sm_cocoaNSTextContainer];
90 if(x)
91 *x=usedRect.size.width;
92 if(y)
93 *y=usedRect.size.height;
94 if(descent)
95 *descent=0;
96 if(externalLeading)
97 *externalLeading=0;
98}
99
100void wxDC::DoDrawText(const wxString& text, wxCoord x, wxCoord y)
101{
102 wxASSERT_MSG(sm_cocoaNSTextStorage && sm_cocoaNSLayoutManager && sm_cocoaNSTextContainer, "Text system has not been initialized. BAD PROGRAMMER!");
103 NSAttributedString *attributedString = [[NSAttributedString alloc]
104 initWithString:[NSString stringWithCString:text.c_str()]];
105 [sm_cocoaNSTextStorage setAttributedString:attributedString];
106 [attributedString release];
107
108 NSRange glyphRange = [sm_cocoaNSLayoutManager glyphRangeForTextContainer:sm_cocoaNSTextContainer];
109 NSRect usedRect = [sm_cocoaNSLayoutManager usedRectForTextContainer:sm_cocoaNSTextContainer];
13fc3db4
DE
110 // NOTE: We'll crash trying to get the location of glyphAtIndex:0 if
111 // there is no length or we don't start at zero
112 if(!glyphRange.length)
113 return;
114 wxASSERT_MSG(glyphRange.location==0,"glyphRange must begin at zero");
891d0563
DE
115
116 NSAffineTransform *transform = [NSAffineTransform transform];
117 [transform translateXBy:x yBy:y];
118
119 NSAffineTransform *flipTransform = [NSAffineTransform transform];
120 /* x' = 1x + 0y + 0
121 y' = 0x + -1y + window's height
122 */
123 NSAffineTransformStruct matrix = {
124 1, 0
125 , 0, -1
126 , 0, usedRect.size.height
127 };
128 [flipTransform setTransformStruct: matrix];
129
130 NSGraphicsContext *context = [NSGraphicsContext currentContext];
131 [context saveGraphicsState];
132 [transform concat];
133 [flipTransform concat];
134 // Draw+fill a rectangle so we can see where the shit is supposed to be.
135 wxLogDebug("(%f,%f) (%fx%f)",usedRect.origin.x,usedRect.origin.y,usedRect.size.width,usedRect.size.height);
136 NSBezierPath *bezpath = [NSBezierPath bezierPathWithRect:NSMakeRect(0,0,usedRect.size.width,usedRect.size.height)];
137 [[NSColor blackColor] set];
138 [bezpath stroke];
139 [[NSColor blueColor] set];
140 [bezpath fill];
141
142 NSPoint layoutLocation = [sm_cocoaNSLayoutManager locationForGlyphAtIndex:0];
143 layoutLocation.x = 0.0;
144 layoutLocation.y *= -1.0;
145 layoutLocation.y += [[sm_cocoaNSLayoutManager typesetter] baselineOffsetInLayoutManager:sm_cocoaNSLayoutManager glyphIndex:0];
146 // NOTE: That's NSMakePoint, not NSMakePint (working on that though)
147 [sm_cocoaNSLayoutManager drawGlyphsForGlyphRange:glyphRange atPoint:layoutLocation];
148
149 [context restoreGraphicsState];
150}
151
2894667f
DE
152// wxDCBase functions
153int wxDCBase::DeviceToLogicalX(int x) const
154{
155 return x;
156}
157
158int wxDCBase::DeviceToLogicalY(int y) const
159{
160 return y;
161}
162
163int wxDCBase::LogicalToDeviceX(int x) const
164{
165 return x;
166}
167
168int wxDCBase::LogicalToDeviceY(int y) const
169{
170 return y;
171}
172
891d0563
DE
173///////////////////////////////////////////////////////////////////////////
174// cut here, the rest is stubs
175///////////////////////////////////////////////////////////////////////////
a24aff65
DE
176
177//-----------------------------------------------------------------------------
178// constants
179//-----------------------------------------------------------------------------
180
181#define mm2inches 0.0393700787402
182#define inches2mm 25.4
183#define mm2twips 56.6929133859
184#define twips2mm 0.0176388888889
185#define mm2pt 2.83464566929
186#define pt2mm 0.352777777778
187
188//-----------------------------------------------------------------------------
189// wxDC
190//-----------------------------------------------------------------------------
191
a24aff65
DE
192void wxDC::DoDrawIcon( const wxIcon &WXUNUSED(icon), int WXUNUSED(x), int WXUNUSED(y) )
193{
194};
195
196void wxDC::DoDrawPoint( int x, int y )
197{
198};
199
200void wxDC::DoDrawPolygon( int, wxPoint *, int, int, int)
201{
202};
203
204void wxDC::DoDrawLines( int, wxPoint *, int, int )
205{
206}
207
a24aff65
DE
208int wxDC::GetDepth() const
209{
210 return 0;
211}
212
213wxSize wxDC::GetPPI() const
214{
215 return wxSize(0,0);
216}
217
218bool wxDC::CanGetTextExtent() const
219{
220 return false;
221}
222
a24aff65
DE
223wxCoord wxDC::GetCharHeight() const
224{
225 return 0;
226}
227
228wxCoord wxDC::GetCharWidth() const
229{
230 return 0;
231}
232
233bool wxDC::CanDrawBitmap() const
234{
235 return false;
236}
237
238bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
239{
240 return false;
241}
242
243void wxDC::DoDrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc)
244{
245}
246
247void wxDC::SetPen(const wxPen& pen)
248{
249}
250
251void wxDC::SetBrush(const wxBrush& brush)
252{
253}
254
255void wxDC::DoSetClippingRegionAsRegion(const wxRegion& region)
256{
257}
258
259void wxDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
260{
261}
262
263void wxDC::DestroyClippingRegion()
264{
265}
266
267void wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius)
268{
269}
270
271void wxDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
272{
273}
274
275void wxDC::DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, double sa, double ea)
276{
277}
278
a24aff65
DE
279void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
280{
281}
282
283void wxDC::DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask)
284{
285}
286
287bool wxDC::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, int style)
288{
289 return false;
290}
291
292void wxDC::DoCrossHair(wxCoord x, wxCoord y)
293{
294}
295
a24aff65
DE
296
297bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask , wxCoord xsrcMask, wxCoord ysrcMask)
298{
299 return false;
300}
301
302void wxDC::DoGetSize( int* width, int* height ) const
303{
304 *width = m_maxX-m_minX;
305 *height = m_maxY-m_minY;
306};
307
308void wxDC::DoGetSizeMM( int* width, int* height ) const
309{
310 int w = 0;
311 int h = 0;
312 GetSize( &w, &h );
313};
314
315void wxDC::SetTextForeground( const wxColour &col )
316{
317 if (!Ok()) return;
318 m_textForegroundColour = col;
319};
320
321void wxDC::SetTextBackground( const wxColour &col )
322{
323 if (!Ok()) return;
324 m_textBackgroundColour = col;
325};
326
327void wxDC::Clear()
328{
329}
330
331void wxDC::SetBackground(const wxBrush&)
332{
333}
334
335void wxDC::SetPalette(const wxPalette&)
336{
337}
338
339void wxDC::SetLogicalFunction(int)
340{
341}
342
343
344void wxDC::SetMapMode( int mode )
345{
346 switch (mode)
347 {
348 case wxMM_TWIPS:
349 break;
350 case wxMM_POINTS:
351 break;
352 case wxMM_METRIC:
353 break;
354 case wxMM_LOMETRIC:
355 break;
356 default:
357 case wxMM_TEXT:
358 SetLogicalScale( 1.0, 1.0 );
359 break;
360 };
361 if (mode != wxMM_TEXT)
362 {
363 };
364};
365
366void wxDC::SetUserScale( double x, double y )
367{
368 // allow negative ? -> no
369 m_userScaleX = x;
370 m_userScaleY = y;
371 ComputeScaleAndOrigin();
372};
373
374void wxDC::SetLogicalScale( double x, double y )
375{
376 // allow negative ?
377 m_logicalScaleX = x;
378 m_logicalScaleY = y;
379 ComputeScaleAndOrigin();
380};
381
382void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y )
383{
384 m_logicalOriginX = x * m_signX; // is this still correct ?
385 m_logicalOriginY = y * m_signY;
386 ComputeScaleAndOrigin();
387};
388
389void wxDC::SetDeviceOrigin( wxCoord x, wxCoord y )
390{
391 ComputeScaleAndOrigin();
392};
393
394void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
395{
396 m_signX = (xLeftRight ? 1 : -1);
397 m_signY = (yBottomUp ? -1 : 1);
398 ComputeScaleAndOrigin();
399};
400
401void wxDC::ComputeScaleAndOrigin(void)
402{
403 // CMB: copy scale to see if it changes
404 double origScaleX = m_scaleX;
405 double origScaleY = m_scaleY;
406
407 m_scaleX = m_logicalScaleX * m_userScaleX;
408 m_scaleY = m_logicalScaleY * m_userScaleY;
409
410 // CMB: if scale has changed call SetPen to recalulate the line width
411 if (m_scaleX != origScaleX || m_scaleY != origScaleY)
412 {
413 // this is a bit artificial, but we need to force wxDC to think
414 // the pen has changed
415 wxPen* pen = & GetPen();
416 wxPen tempPen;
417 m_pen = tempPen;
418 SetPen(* pen);
419 }
420};
421