Fixes for uncommon drawRect: bugs.

Reviewed by me.
This commit is contained in:
Francisco Ryan Tolmasky I committed 2009-08-30 20:59:01 -07:00
1 parent 75060a3385
commit 2cf5b90183
4 files changed
+216 -203

No files matched your search

+6 -16
View File
@@ -27,11 +27,11 @@
@import "CGGeometry.j"
@import "CPColor.j"
@import "CPDOMDisplayServer.j"
@import "CPGeometry.j"
@import "CPGraphicsContext.j"
@import "CPResponder.j"
@import "CPTheme.j"
@import "_CPDisplayServer.j"
#include "Platform/Platform.h"
@@ -1562,10 +1562,6 @@ setBoundsOrigin:
{
if (aFlag)
[self setNeedsDisplayInRect:[self bounds]];
#if PLATFORM(DOM)
else
CPDOMDisplayServerRemoveView(self);
#endif
}
/*!
@@ -1574,22 +1570,18 @@ setBoundsOrigin:
*/
- (void)setNeedsDisplayInRect:(CPRect)aRect
{
#if PLATFORM(DOM)
if (!(_viewClassFlags & CPViewHasCustomDrawRect))
return;
#endif
if (_CGRectIsEmpty(aRect))
return;
if (_dirtyRect && !_CGRectIsEmpty(_dirtyRect))
_dirtyRect = CGRectUnion(aRect, _dirtyRect);
else
_dirtyRect = _CGRectMakeCopy(aRect);
#if PLATFORM(DOM)
CPDOMDisplayServerAddView(self);
#endif
_CPDisplayServerAddDisplayObject(self);
}
- (BOOL)needsDisplay
@@ -1695,13 +1687,11 @@ setBoundsOrigin:
- (void)setNeedsLayout
{
_needsLayout = YES;
#if PLATFORM(DOM)
if (!(_viewClassFlags & CPViewHasCustomLayoutSubviews))
return;
CPDOMDisplayServerAddView(self);
#endif
_CPDisplayServerAddLayoutObject(self);
}
- (void)layoutIfNeeded
+109 -22
View File
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define DOM_OPTIMIZATION 1
#define SetStyleOrigin 0
#define SetStyleLeftTop 0
#define SetStyleRightTop 1
@@ -45,7 +47,49 @@
CPDOMDisplayServerInstructions[__index + 2] = aTransform;\
CPDOMDisplayServerInstructions[__index + 3] = x;\
CPDOMDisplayServerInstructions[__index + 4] = y;
#if !DOM_OPTIMIZATION
#define CPDOMDisplayServerSetStyleLeftTop(aDOMElement, aTransform, aLeft, aTop) \
if (aTransform) var ____p = _CGPointApplyAffineTransform(CGPointMake(aLeft, aTop), aTransform); \
else var ____p = _CGPointMake(aLeft, aTop); \
aDOMElement.style.left = ROUND(____p.x) + "px";\
aDOMElement.style.top = ROUND(____p.y) + "px";
#define CPDOMDisplayServerSetStyleRightTop(aDOMElement, aTransform, aRight, aTop) \
if (aTransform) var ____p = _CGPointApplyAffineTransform(CGPointMake(aRight, aTop), aTransform); \
else var ____p = _CGPointMake(aRight, aTop); \
aDOMElement.style.right = ROUND(____p.x) + "px";\
aDOMElement.style.top = ROUND(____p.y) + "px";
#define CPDOMDisplayServerSetStyleLeftBottom(aDOMElement, aTransform, aLeft, aBottom) \
if (aTransform) var ____p = _CGPointApplyAffineTransform(CGPointMake(aLeft, aBottom), aTransform); \
else var ____p = _CGPointMake(aLeft, aBottom); \
aDOMElement.style.left = ROUND(____p.x) + "px";\
aDOMElement.style.bottom = ROUND(____p.y) + "px";
#define CPDOMDisplayServerSetStyleRightBottom(aDOMElement, aTransform, aRight, aBottom) \
if (aTransform) var ____p = _CGPointApplyAffineTransform(CGPointMake(aRight, aBottom), aTransform); \
else var ____p = _CGPointMake(aRight, aBottom); \
aDOMElement.style.right = ROUND(____p.x) + "px";\
aDOMElement.style.bottom = ROUND(____p.y) + "px";
#define CPDOMDisplayServerSetStyleSize(aDOMElement, aWidth, aHeight) \
aDOMElement.style.width = MAX(0.0, ROUND(aWidth)) + "px";\
aDOMElement.style.height = MAX(0.0, ROUND(aHeight)) + "px";
#define CPDOMDisplayServerSetSize(aDOMElement, aWidth, aHeight) \
aDOMElement.width = MAX(0.0, ROUND(aWidth));\
aDOMElement.height = MAX(0.0, ROUND(aHeight));
#define CPDOMDisplayServerAppendChild(aParentElement, aChildElement) aParentElement.appendChild(aChildElement)
#define CPDOMDisplayServerInsertBefore(aParentElement, aChildElement, aBeforeElement) aParentElement.insertBefore(aChildElement, aBeforeElement)
#define CPDOMDisplayServerRemoveChild(aParentElement, aChildElement) aParentElement.removeChild(aChildElement)
#define PREPARE_DOM_OPTIMIZATION()
#define EXECUTE_DOM_INSTRUCTIONS()
#else
#define CPDOMDisplayServerSetStyleLeftTop(aDOMElement, aTransform, aLeft, aTop) CPDOMDisplayServerSetStyleOrigin(SetStyleLeftTop, aDOMElement, aTransform, aLeft, aTop)
#define CPDOMDisplayServerSetStyleRightTop(aDOMElement, aTransform, aRight, aTop) CPDOMDisplayServerSetStyleOrigin(SetStyleRightTop, aDOMElement, aTransform, aRight, aTop)
@@ -99,27 +143,70 @@
CPDOMDisplayServerInstructions[CPDOMDisplayServerInstructionCount++] = RemoveChild;\
CPDOMDisplayServerInstructions[CPDOMDisplayServerInstructionCount++] = aParentElement;\
CPDOMDisplayServerInstructions[CPDOMDisplayServerInstructionCount++] = aChildElement;
//#dfeine CPDOMDisplayServerCustomAction()
#define CPDOMDisplayServerAddView(aView)\
#define PREPARE_DOM_OPTIMIZATION()\
CPDOMDisplayServerInstructions = [];\
CPDOMDisplayServerInstructionCount = 0;
#define EXECUTE_DOM_INSTRUCTIONS()\
var index = 0;\
while (index < CPDOMDisplayServerInstructionCount)\
{\
var ___UID = [aView UID];\
if (typeof (CPDOMDisplayServerViewsContext[___UID]) == "undefined")\
{\
CPDOMDisplayServerViews[CPDOMDisplayServerViewsCount++] = aView;\
CPDOMDisplayServerViewsContext[___UID] = aView;\
var instruction = CPDOMDisplayServerInstructions[index++];\
try{\
switch (instruction)\
{\
case SetStyleLeftTop:\
case SetStyleRightTop:\
case SetStyleLeftBottom:\
case SetStyleRightBottom: var element = CPDOMDisplayServerInstructions[index],\
style = element.style,\
x = (instruction == SetStyleLeftTop || instruction == SetStyleLeftBottom) ? "left" : "right",\
y = (instruction == SetStyleLeftTop || instruction == SetStyleRightTop) ? "top" : "bottom";\
CPDOMDisplayServerInstructions[index++] = nil;\
var transform = CPDOMDisplayServerInstructions[index++];\
if (transform)\
{\
var point = _CGPointMake(CPDOMDisplayServerInstructions[index++], CPDOMDisplayServerInstructions[index++]),\
transformed = _CGPointApplyAffineTransform(point, transform);\
style[x] = ROUND(transformed.x) + "px";\
style[y] = ROUND(transformed.y) + "px";\
}\
else\
{\
style[x] = ROUND(CPDOMDisplayServerInstructions[index++]) + "px";\
style[y] = ROUND(CPDOMDisplayServerInstructions[index++]) + "px";\
}\
element.CPDOMDisplayContext[SetStyleOrigin] = -1;\
break;\
case SetStyleSize: var element = CPDOMDisplayServerInstructions[index],\
style = element.style;\
CPDOMDisplayServerInstructions[index++] = nil;\
element.CPDOMDisplayContext[SetStyleSize] = -1;\
style.width = MAX(0.0, ROUND(CPDOMDisplayServerInstructions[index++])) + "px";\
style.height = MAX(0.0, ROUND(CPDOMDisplayServerInstructions[index++])) + "px";\
break;\
case SetSize: var element = CPDOMDisplayServerInstructions[index];\
CPDOMDisplayServerInstructions[index++] = nil;\
element.CPDOMDisplayContext[SetSize] = -1;\
element.width = MAX(0.0, ROUND(CPDOMDisplayServerInstructions[index++]));\
element.height = MAX(0.0, ROUND(CPDOMDisplayServerInstructions[index++]));\
break;\
case AppendChild: CPDOMDisplayServerInstructions[index].appendChild(CPDOMDisplayServerInstructions[index + 1]);\
CPDOMDisplayServerInstructions[index++] = nil;\
CPDOMDisplayServerInstructions[index++] = nil;\
break;\
case InsertBefore: CPDOMDisplayServerInstructions[index].insertBefore(CPDOMDisplayServerInstructions[index + 1], CPDOMDisplayServerInstructions[index + 2]);\
CPDOMDisplayServerInstructions[index++] = nil;\
CPDOMDisplayServerInstructions[index++] = nil;\
CPDOMDisplayServerInstructions[index++] = nil;\
break;\
case RemoveChild: CPDOMDisplayServerInstructions[index].removeChild(CPDOMDisplayServerInstructions[index + 1]);\
CPDOMDisplayServerInstructions[index++] = nil;\
CPDOMDisplayServerInstructions[index++] = nil;\
break;\
}\
}\
catch(e) { CPLog("e " + e + " " + instruction); }\
}\
}\
#define CPDOMDisplayServerRemoveView(aView)\
{\
var index = CPDOMDisplayServerViewsContext[[aView UID]];\
if (typeof index != "undefined") \
{\
CPDOMDisplayServerViewsContext[[aView UID]];\
CPDOMDisplayServerViews[index] = NULL;\
}\
}\
CPDOMDisplayServerInstructionCount = 0;
#endif
-165
View File
@@ -1,165 +0,0 @@
/*
* CPDOMDisplayServer.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPRunLoop.j>
#include "../../CoreGraphics/CGAffineTransform.h"
#include "CPDOMDisplayServer.h"
var CPDOMDisplayRunLoop = nil;
CPDOMDisplayServerInstructions = [];
CPDOMDisplayServerInstructionCount = 0;
CPDOMDisplayServerViews = [];
CPDOMDisplayServerViewsCount = 0;
CPDOMDisplayServerViewsContext = {};
@implementation CPDOMDisplayServer : CPObject
{
}
+ (void)start
{
CPDOMDisplayRunLoop = [CPRunLoop currentRunLoop];
[CPDOMDisplayRunLoop performSelector:@selector(run) target:CPDOMDisplayServer argument:nil order:0 modes:[CPDefaultRunLoopMode]];
}
+ (void)run
{
while (CPDOMDisplayServerInstructionCount || CPDOMDisplayServerViewsCount)
{
var index = 0;
while (index < CPDOMDisplayServerInstructionCount)
{
var instruction = CPDOMDisplayServerInstructions[index++];
try{
switch (instruction)
{
case SetStyleLeftTop:
case SetStyleRightTop:
case SetStyleLeftBottom:
case SetStyleRightBottom: var element = CPDOMDisplayServerInstructions[index],
style = element.style,
x = (instruction == SetStyleLeftTop || instruction == SetStyleLeftBottom) ? "left" : "right",
y = (instruction == SetStyleLeftTop || instruction == SetStyleRightTop) ? "top" : "bottom";
CPDOMDisplayServerInstructions[index++] = nil;
var transform = CPDOMDisplayServerInstructions[index++];
if (transform)
{
var point = _CGPointMake(CPDOMDisplayServerInstructions[index++], CPDOMDisplayServerInstructions[index++]),
transformed = _CGPointApplyAffineTransform(point, transform);
style[x] = ROUND(transformed.x) + "px";
style[y] = ROUND(transformed.y) + "px";
}
else
{
style[x] = ROUND(CPDOMDisplayServerInstructions[index++]) + "px";
style[y] = ROUND(CPDOMDisplayServerInstructions[index++]) + "px";
}
element.CPDOMDisplayContext[SetStyleOrigin] = -1;
break;
case SetStyleSize: var element = CPDOMDisplayServerInstructions[index],
style = element.style;
CPDOMDisplayServerInstructions[index++] = nil;
element.CPDOMDisplayContext[SetStyleSize] = -1;
style.width = MAX(0.0, ROUND(CPDOMDisplayServerInstructions[index++])) + "px";
style.height = MAX(0.0, ROUND(CPDOMDisplayServerInstructions[index++])) + "px";
break;
case SetSize: var element = CPDOMDisplayServerInstructions[index];
CPDOMDisplayServerInstructions[index++] = nil;
element.CPDOMDisplayContext[SetSize] = -1;
element.width = MAX(0.0, ROUND(CPDOMDisplayServerInstructions[index++]));
element.height = MAX(0.0, ROUND(CPDOMDisplayServerInstructions[index++]));
break;
case AppendChild: CPDOMDisplayServerInstructions[index].appendChild(CPDOMDisplayServerInstructions[index + 1]);
CPDOMDisplayServerInstructions[index++] = nil;
CPDOMDisplayServerInstructions[index++] = nil;
break;
case InsertBefore: CPDOMDisplayServerInstructions[index].insertBefore(CPDOMDisplayServerInstructions[index + 1], CPDOMDisplayServerInstructions[index + 2]);
CPDOMDisplayServerInstructions[index++] = nil;
CPDOMDisplayServerInstructions[index++] = nil;
CPDOMDisplayServerInstructions[index++] = nil;
break;
case RemoveChild: CPDOMDisplayServerInstructions[index].removeChild(CPDOMDisplayServerInstructions[index + 1]);
CPDOMDisplayServerInstructions[index++] = nil;
CPDOMDisplayServerInstructions[index++] = nil;
break;
}}catch(e) { CPLog("here?" + instruction) }
}
CPDOMDisplayServerInstructionCount = 0;
var views = CPDOMDisplayServerViews,
index = 0,
count = CPDOMDisplayServerViewsCount;
// We don't reset CPDOMDisplayServerViewsContext because it can serve for displays that are coming...
CPDOMDisplayServerViews = [];
CPDOMDisplayServerViewsCount = 0;
for (; index < count; ++index)
{
var view = views[index];
delete CPDOMDisplayServerViewsContext[[view UID]];
[view layoutIfNeeded];
[view displayIfNeeded];
}
}
[CPDOMDisplayRunLoop performSelector:@selector(run) target:CPDOMDisplayServer argument:nil order:0 modes:[CPDefaultRunLoopMode]];
}
@end
[CPDOMDisplayServer start];
+101
View File
@@ -0,0 +1,101 @@
/*
* _CPDisplayServer.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "CoreGraphics/CGGeometry.h"
#include "CoreGraphics/CGAffineTransform.h"
#include "Platform/DOM/CPDOMDisplayServer.h"
PREPARE_DOM_OPTIMIZATION();
var displayObjects = [],
displayObjectsByUID = { },
layoutObjects = [],
layoutObjectsByUID = { },
runLoop = [CPRunLoop mainRunLoop];
function _CPDisplayServerAddDisplayObject(anObject)
{
var UID = [anObject UID];
if (typeof displayObjectsByUID[UID] !== "undefined")
return;
var index = displayObjects.length;
displayObjectsByUID[UID] = index;
displayObjects[index] = anObject;
}
function _CPDisplayServerAddLayoutObject(anObject)
{
var UID = [anObject UID];
if (typeof layoutObjectsByUID[UID] !== "undefined")
return;
var index = layoutObjects.length;
layoutObjectsByUID[UID] = index;
layoutObjects[index] = anObject;
}
@implementation _CPDisplayServer : CPObject
{
}
+ (void)run
{
var index = 0;
for (; index < layoutObjects.length; ++index)
{
var object = layoutObjects[index];
delete layoutObjectsByUID[[object UID]];
[object layoutIfNeeded];
}
EXECUTE_DOM_INSTRUCTIONS();
layoutObjects = [];
layoutObjectsByUID = { };
index = 0;
var count = displayObjects.length;
for (; index < count; ++index)
[displayObjects[index] displayIfNeeded];
EXECUTE_DOM_INSTRUCTIONS();
displayObjects = [];
displayObjectsByUID = { };
[runLoop performSelector:@selector(run) target:self argument:nil order:0 modes:[CPDefaultRunLoopMode]];
}
@end
[_CPDisplayServer run];