void DisplayElement::InvalidateChild (DisplayElement *pChild, WebRect *pDirty) { WebRect dirty; dirty.Set(pDirty); dirty.Shift(mRect.left, mRect.top); if (GetOverflow() == DISPLAY_OVERFLOW_HIDDEN) { WebRect clipRect; GetClipRect(&clipRect); // If completely outside clipping rect, stop here if (!dirty.Overlaps(&clipRect)) { return; } // clip pDirty to our rect dirty.And(&clipRect); } if ((mFlags & DISPLAY_FLAG_FIXED_POS) || !mpParent) { DisplayManager *pManager = GetManager(); if (pManager) { if (mFlags & DISPLAY_FLAG_FIXED_POS) { dirty.Shift(pManager->mViewRect.left, pManager->mViewRect.top); } pManager->InvalidateViewportRegion(&dirty); } } else { mpParent->InvalidateChild(this, &dirty); } }
void DisplayManager::UpdateScrollBuffer (void) { if ((GetManagerFlags() & MANAGER_FLAG_DIRTY) && mRoot.Get() && mScrollBuffer) { WebRect* dirty; ClearManagerFlag(MANAGER_FLAG_BUFFER_DIRTY); // move the dirty rectangle list onto the stack so it can't be corrupted vector dirtyListCopy = mDirtyList; mDirtyList.first = 0; mDirtyList.last = 0; vector_iterator vi; DISPLAY_INT viewWidth = mViewRect.Width(); DISPLAY_INT viewHeight = mViewRect.Height(); PresetWebRect viewCorner(&mViewRect); viewCorner.MoveTo(0,0); PresetWebRect bufferView(&mViewRect); bufferView.MoveTo(mViewRect.left % viewWidth, mViewRect.top % viewHeight); DISPLAY_INT bufferLeft = mViewRect.left - (mViewRect.left % viewWidth); DISPLAY_INT bufferTop = mViewRect.top - (mViewRect.top % viewHeight); dirty = (WebRect*) vector_get_first(&dirtyListCopy, &vi); while (dirty) { if (mViewRect.Overlaps(dirty)) { WebRect bufferDirty; bufferDirty.left = dirty->left - bufferLeft; bufferDirty.top = dirty->top - bufferTop; bufferDirty.SizeTo(dirty->Width(), dirty->Height()); bufferDirty.And(&bufferView); mScrollBuffer->SetClip(&bufferDirty); DISPLAY_INT x = mRoot.Get()->mRect.left - bufferLeft; DISPLAY_INT y = mRoot.Get()->mRect.top - bufferTop; mRoot.Get()->Draw (x, y, &bufferView, mScrollBuffer); PresetWebRect defaultClip(0, 0, viewWidth * 2 - 1, viewHeight * 2 - 1); mScrollBuffer->SetClip(&defaultClip); // copy bufferDirty 3 times, split if necessary PresetWebRect northwest (0, 0, viewWidth - 1, viewHeight - 1); PresetWebRect northeast (viewWidth, 0, viewWidth * 2 - 1, viewHeight - 1); PresetWebRect southeast (viewWidth, viewHeight, viewWidth * 2 - 1, viewHeight * 2 - 1); PresetWebRect southwest (0, viewHeight, viewWidth - 1, viewHeight * 2 - 1); if (bufferDirty.Overlaps(&northwest)) { PresetWebRect copyFrom (&bufferDirty); copyFrom.And(&northwest); PresetWebRect copyTo (©From); copyTo.ShiftOver(mViewRect.Width()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); copyTo.ShiftDown(mViewRect.Height()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); copyTo.ShiftOver(-mViewRect.Width()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); } if (bufferDirty.Overlaps(&northeast)) { PresetWebRect copyFrom (&bufferDirty); copyFrom.And(&northeast); PresetWebRect copyTo (©From); copyTo.ShiftDown(mViewRect.Height()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); copyTo.ShiftOver(-mViewRect.Width()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); copyTo.ShiftDown(-mViewRect.Height()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); } if (bufferDirty.Overlaps(&southeast)) { PresetWebRect copyFrom (&bufferDirty); copyFrom.And(&southeast); PresetWebRect copyTo (©From); copyTo.ShiftDown(-mViewRect.Height()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); copyTo.ShiftOver(-mViewRect.Width()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); copyTo.ShiftDown(mViewRect.Height()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); } if (bufferDirty.Overlaps(&southwest)) { PresetWebRect copyFrom (&bufferDirty); copyFrom.And(&southwest); PresetWebRect copyTo (©From); copyTo.ShiftDown(-mViewRect.Height()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); copyTo.ShiftOver(mViewRect.Width()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); copyTo.ShiftDown(mViewRect.Height()); mScrollBuffer->CopyBufferRegion(©To, mScrollBuffer, copyFrom.left, copyFrom.top); } } dirty = (WebRect*) vector_get_next(&vi); } // this ensures the dirty list is just the same as when we entered vector_delete(&mDirtyList); if (!this->GetManager()) { // if we're the root manager, we'll need this list in a sec. mDirtyList = dirtyListCopy; } else { ClearManagerFlag(MANAGER_FLAG_DIRTY); vector_delete(&dirtyListCopy); } } }
void WebDropBox::DrawThisOnly (DISPLAY_INT x, DISPLAY_INT y, WebGraphics *gc) { WEBC_BOOL focused = (mFlags & DISPLAY_FLAG_FOCUS) || (mState == DROPBOX_STATE_DROPPED); mListbox.CalculateTextMetrics(gc); WebRect oldClip; gc->GetClip(&oldClip); WebRect clip; clip.top = y; clip.left = x; clip.bottom = y + Height() - 1; clip.right = x + Width() - 1; clip.And(&oldClip); gc->SetClip(&clip); WebRect rect; rect.top = y; rect.left = x; rect.bottom = y + Height() - 1; rect.right = x + Width() - 1; // gc->StartBuffer(); WebColor hilite, lolite, blue, white, black; HTMLColor col = HTML_RGBAToColor(0,0,0,0); black = hilite = gc->RGBToColor(col); col = HTML_RGBAToColor(0xff,0xff,0xff,0); white = lolite = gc->RGBToColor(col); col = HTML_RGBAToColor(0,0,0xff,0); blue = gc->RGBToColor(col); if (focused) { gc->Rectangle(&rect, black, black, WEBC_FALSE); } GetFrameRect(&rect); rect.Shift(x,y); DrawFrame(&rect, gc); GetContentRect(&rect); rect.Shift(x,y); if (focused) { gc->Rectangle(&rect, GetSelectColor(gc), GetSelectColor(gc), WEBC_TRUE); } else { gc->Rectangle(&rect, GetBgColor(gc), GetBgColor(gc), WEBC_TRUE); } if (mpText && mFont.GetFont()) { DISPLAY_INT offset = (rect.Height() - gc->TextHeight(mpText, mFont.GetFont())) / 2; clip.Set(&rect); clip.And(&oldClip); gc->SetClip(&clip); gc->Text(rect.left + DROPBOX_PADDING, rect.top + DROPBOX_PADDING + offset, mpText, (focused) ? GetBgColor(gc) : GetTextColor(gc), 0, WEBC_FALSE, mFont.GetFont()); } // gc->EndBuffer(); gc->SetClip(&oldClip); }