The reason that the vertical scrolling is affected but not the horizontal scrolling is that there is a scrollbar to the left of the graph, and its vertical bounds are not the same as the graph's. And when the graph is scrolled vertically, the scrollbar invalidates (as well as the graph), and that causes the graph to get two drawRect() calls instead of one: one for the vertical area matching the scrollbar bounds, and one for the vertical area of the graph outside the scrollbar's vertical bounds.
In trying to figure out what is happening, and why this second call is causing a problem, I found that the difference occurs in the call CGDrawContext::drawBitmap(). I am posting that code below so you can see what I am referring to more easily.
When the first of the two drawRect() calls happens in the graph (or if only one such call is made, as in the horizontal scroll case), the code enters the "if (it == bitmapDrawCount.end ())" block, which calls bitmapDrawCount.insert(). But on the second drawRect() call, it enters the "else" block, which calls cgBitmap->createCGLayer(). It is this call to createCGLayer() that appears to be taking the extra time when drawing after a vertical scroll.
Code: Select all
void CGDrawContext::drawBitmap (CBitmap* bitmap, const CRect& inRect, const CPoint& inOffset, float alpha)
if (bitmap == 0 || alpha == 0.f)
double transformedScaleFactor = scaleFactor;
CGraphicsTransform t = getCurrentTransform ();
if (t.m11 == t.m22 && t.m12 == 0 && t.m21 == 0)
transformedScaleFactor *= t.m11;
IPlatformBitmap* platformBitmap = bitmap->getBestPlatformBitmapForScaleFactor (transformedScaleFactor);
CGBitmap* cgBitmap = platformBitmap ? dynamic_cast<CGBitmap*> (platformBitmap) : 0;
CGImageRef image = cgBitmap ? cgBitmap->getCGImage () : 0;
CGContextRef context = beginCGContext (false, false);
CGLayerRef layer = cgBitmap->getCGLayer ();
if (layer == 0)
BitmapDrawCountMap::iterator it = bitmapDrawCount.find (cgBitmap);
if (it == bitmapDrawCount.end ())
bitmapDrawCount.insert (std::pair<CGBitmap*, int32_t> (cgBitmap, 1));
layer = cgBitmap->createCGLayer (context);
drawCGImageRef (context, image, layer, cgBitmap->getScaleFactor (), inRect, inOffset, alpha, bitmap);
I really don't know what this code is doing in either case, since it's not documented here. Can someone let me know if this code is correct? Somehow it seems kind of backwards to me, in that I would expect the first time through that you'd create something and add it to a list or something, so that subsequent calls could skip creating the object. But as I said, I don't really know what this code is actually doing.
Can anyone help? We're getting a lot of complaints about this.