예제 #1
0
void WebViewHost::paintInvalidatedRegion()
{
#if ENABLE(REQUEST_ANIMATION_FRAME)
    webWidget()->animate(0.0);
#endif
    webWidget()->layout();
    WebSize widgetSize = webWidget()->size();
    WebRect clientRect(0, 0, widgetSize.width, widgetSize.height);

    // Paint the canvas if necessary. Allow painting to generate extra rects
    // for the first two calls. This is necessary because some WebCore rendering
    // objects update their layout only when painted.
    // Store the total area painted in total_paint. Then tell the gdk window
    // to update that area after we're done painting it.
    for (int i = 0; i < 3; ++i) {
        // rect = intersect(proxy()->paintRect() , clientRect)
        WebRect damageRect = proxy()->paintRect();
        int left = max(damageRect.x, clientRect.x);
        int top = max(damageRect.y, clientRect.y);
        int right = min(damageRect.x + damageRect.width, clientRect.x + clientRect.width);
        int bottom = min(damageRect.y + damageRect.height, clientRect.y + clientRect.height);
        WebRect rect;
        if (left < right && top < bottom)
            rect = WebRect(left, top, right - left, bottom - top);

        proxy()->setPaintRect(WebRect());
        if (rect.isEmpty())
            continue;
        paintRect(rect);
    }
    ASSERT(proxy()->paintRect().isEmpty());
}
예제 #2
0
void DisplayElement::GetBounds (WebRect *rect)
{
	if (mFlags & DISPLAY_FLAG_BOUNDS_VALID)
	{
		*rect = mBounds;
		return;
	}

	*rect = mRect;

	WebRect childRect;
	DisplayElement *pChild = mpFirstChild;

	while (pChild)
	{
		if (!(pChild->mFlags & DISPLAY_FLAG_FIXED_POS))
		{
			pChild->GetBounds(&childRect);
			childRect.Shift(mRect.left, mRect.top);
			rect->Or(&childRect);
		}

		pChild = pChild->mpNext;
	}

	SetFlag(DISPLAY_FLAG_BOUNDS_VALID);
	mBounds = *rect;
}
예제 #3
0
/*---------------------------------------------------------------------------*/
void HTMLBodyDisplay::Draw (DISPLAY_INT x, DISPLAY_INT y, WebRect *pViewport, WebGraphics *pGC)
{
	FormatIfNecessary();

  #if (WEBC_SUPPORT_FRAMES)
	if (mpFrameSet)
	{
		mpFrameSet->Draw(x, y, pViewport, pGC);
	}
	else
  #endif //	WEBC_SUPPORT_FRAMES
	{
		if (!(mpHtmlElement->mFlags & HBODY_FLAG_NOBACKGROUND))
		{
			WebRect screenRect;
			screenRect.Set(x, y, pViewport->right, pViewport->bottom);
			DrawBackground(&screenRect, pViewport, pGC);
		}

		// Draw all children
		DisplayElement *pChild = mpFirstChild;
		while (pChild)
		{
			if (pChild->mFlags & DISPLAY_FLAG_FIXED_POS)
			{
				pChild->Draw(pViewport->left + pChild->mRect.left, pViewport->top + pChild->mRect.top, pViewport, pGC);
			}
			else
			{
				pChild->Draw(x + pChild->mRect.left, y + pChild->mRect.top, pViewport, pGC);
			}
			pChild = pChild->mpNext;
		}
	}
}
예제 #4
0
int HTMLString::GetDocumentDisplayRect (WebRect *rect, int n)
{
WebRect displayRect;
HTMLStringDisplay *display = mpFirstDisplay;

	while (display && n > 0)
	{
		if (display->GetStringIndex() + display->GetStringLength() >= miLength)
		{
			display = 0;
			break;
		}
		n--;
		display = display->GetNextSubString();
	}

	if (display)
	{
		displayRect.Set(&display->mRect);

		if (display->mpParent)
		{
			DISPLAY_INT x, y;

			display->mpParent->GetDisplayPosition(display, &x, &y);
			displayRect.MoveTo(x,y);
		}

		rect->Set(&displayRect);

		return (0);
	}

	return (-1);
}
예제 #5
0
void DisplayManager::CorrectViewportPosition (void)
{
	if (mRoot.Get())
	{
		WebRect bounds;
		PresetWebRect rect(&mViewRect);

		GetRootBounds(&bounds);
		rect.MoveTo(0,0);
		bounds.Or(&rect);

		if (mViewRect.left < bounds.left)
		{
			mViewRect.Shift(bounds.left - mViewRect.left, 0);
		}

		if (mViewRect.right > bounds.right)
		{
			mViewRect.Shift(bounds.right - mViewRect.right, 0);
		}

		if (mViewRect.top < bounds.top)
		{
			mViewRect.Shift(0, bounds.top - mViewRect.top);
		}

		if (mViewRect.bottom > bounds.bottom)
		{
			mViewRect.Shift(0, bounds.bottom - mViewRect.bottom);
		}

		if (mpVScroll)
		{
			// Range and Window must be set BEFORE Position,
			//  so position is not unjustly clipped!
			mpVScroll->SetRange(bounds.Height());
			mpVScroll->SetWindow(mViewRect.Height());
			mpVScroll->SetPosition(mViewRect.top);
		}

		if (mpHScroll)
		{
			// Range and Window must be set BEFORE Position,
			//  so position is not unjustly clipped!
			mpHScroll->SetRange(bounds.Width());
			mpHScroll->SetWindow(mViewRect.Width());
			mpHScroll->SetPosition(mViewRect.left);
		}
	}
}
예제 #6
0
void WebListBox::ResizeScrollBars(void)
{
	if (mpHScroll)
	{
		WebRect r;
		r.Set(GetMargin() + GetBorder(),
		      Height() - GetMargin() - GetBorder() - miSliderWidth - 1,
		      Width() - (mpVScroll ? miSliderWidth : 0) - GetMargin() - GetBorder() - 1,
		      Height() - GetMargin() - GetBorder() - 1);
		mpHScroll->Move(&r);
		WebRect vr;
		GetOptionsRect(&vr);
		mpHScroll->SetWindow(vr.Width());
		mpHScroll->Invalidate();
	}
	if (mpVScroll)
	{
		WebRect r;
		r.Set(Width() - 1 - GetMargin() - GetBorder() - miSliderWidth,
		      GetMargin() + GetBorder(),
		      Width() - 1 - GetMargin() - GetBorder(),
		      Height() - 1 - (mpHScroll ? miSliderWidth : 0) - GetMargin() - GetBorder());
		mpVScroll->Move(&r);
		WebRect vr;
		GetOptionsRect(&vr);
		mpVScroll->SetWindow(vr.Height());
		mpVScroll->Invalidate();

	}
}
예제 #7
0
void WebPopupMenuImpl::paint(WebCanvas* canvas, const WebRect& rect)
{
    if (!m_widget)
        return;

    if (!rect.isEmpty())
        m_widget->paint(&GraphicsContextBuilder(canvas).context(), rect);
}
예제 #8
0
void WebPopupMenuImpl::paintContents(WebCanvas* canvas, const WebRect& rect, bool, WebFloatRect&)
{
    if (!m_widget)
        return;

    if (!rect.isEmpty()) {
        GraphicsContext context(canvas);
        m_widget->paint(&context, rect);
    }
}
예제 #9
0
void DisplayManager::UpdateViewport (void)
{
	WebRect view;
	WebRect padding;
	WebRect vscrollRect;
	WebRect hscrollRect;

	GetPaddingWidth(&padding);

	view.Set (mRect.left + padding.left,
	          mRect.top + padding.top,
	          mRect.right - padding.right,
	          mRect.bottom - padding.bottom);

	if (mpVScroll)
	{
		vscrollRect.Set (mRect.Width() - padding.right - webc_GetDefaultDisplayInt(WEBC_DEFAULT_SLIDER_WIDTH), padding.top,
		                 mRect.Width() - 1 - padding.right, mRect.Height() - 1 - padding.bottom);

		view.right -= webc_GetDefaultDisplayInt(WEBC_DEFAULT_SLIDER_WIDTH);

		if (mpHScroll)
		{
			hscrollRect.Set (padding.left, mRect.Height() - padding.bottom - webc_GetDefaultDisplayInt(WEBC_DEFAULT_SLIDER_WIDTH),
			                 mRect.Width() - padding.right - webc_GetDefaultDisplayInt(WEBC_DEFAULT_SLIDER_WIDTH),
			                 mRect.Height() - 1 - padding.bottom);

			vscrollRect.bottom -= webc_GetDefaultDisplayInt(WEBC_DEFAULT_SLIDER_WIDTH) - 1;
			view.bottom -= webc_GetDefaultDisplayInt(WEBC_DEFAULT_SLIDER_WIDTH);

			mpHScroll->Move(&hscrollRect);
		}

		mpVScroll->Move(&vscrollRect);
	}
	else
	{
		if (mpHScroll)
		{
			hscrollRect.Set (padding.left, mRect.Height() - padding.bottom - webc_GetDefaultDisplayInt(WEBC_DEFAULT_SLIDER_WIDTH),
			                 mRect.Width() - 1 - padding.right,
			                 mRect.Height() - 1 - padding.bottom);

			view.bottom -= webc_GetDefaultDisplayInt(WEBC_DEFAULT_SLIDER_WIDTH);

			mpHScroll->Move(&hscrollRect);
		}
	}

	view.MoveTo(mViewRect.left, mViewRect.top);
	SetViewport(&view);
}
예제 #10
0
FormatResult HTMLBodyDisplay::FormatForViewport (
		WebRect* viewportRect,
		WEBC_BOOL hscrollPresent,
		WEBC_BOOL vscrollPresent
	)
{
	if (Width() != viewportRect->Width())
	{
		SizeTo(viewportRect->Width(), viewportRect->Height());
		SetParentStyleModified();
	}
	else if (Height() != viewportRect->Height())
	{
		SizeTo(viewportRect->Width(), viewportRect->Height());
		SetPosChildStyleModified();
	}

	FormatIfNecessary();
	CSSPropertyValue overflowValue;
	if (mpHtmlElement->GetStyleFromCSS(CSS_PROPERTY_OVERFLOW, &overflowValue) == CSS_VALUE_SPECIFIED)
	{
		if (CSS_OVERFLOW_HIDDEN == overflowValue.overflow)
		{
			return (DISPLAY_FORMAT_SUCCESS);
		}
	}
#if (WEBC_SUPPORT_SCROLLBARS)
	WebRect bounds;
	GetBounds(&bounds);

	if (bounds.Height() > viewportRect->Height() && !vscrollPresent)
	{
		return (DISPLAY_FORMAT_NEEDS_VSCROLL);
	}

	if (bounds.Width() > viewportRect->Width() && !hscrollPresent)
	{
		return (DISPLAY_FORMAT_NEEDS_HSCROLL);
	}
#endif
	return (DISPLAY_FORMAT_SUCCESS);
}
예제 #11
0
void WebPopupMenuImpl::paint(WebCanvas* canvas, const WebRect& rect, PaintOptions)
{
    if (!m_widget)
        return;

    if (!rect.isEmpty()) {
        GraphicsContext context(canvas);
        context.applyDeviceScaleFactor(m_client->deviceScaleFactor());
        m_widget->paint(&context, rect);
    }
}
예제 #12
0
void WebPopupMenuImpl::paintContents(WebCanvas* canvas, const WebRect& rect, bool, WebContentLayerClient::GraphicsContextStatus contextStatus)
{
    if (!m_widget)
        return;

    if (!rect.isEmpty()) {
        GraphicsContext context(canvas,
                                contextStatus == WebContentLayerClient::GraphicsContextEnabled ? GraphicsContext::NothingDisabled : GraphicsContext::FullyDisabled);
        m_widget->paint(&context, rect);
    }
}
예제 #13
0
void WebPopupMenuImpl::paint(WebCanvas* canvas, const WebRect& rect)
{
    if (!m_widget)
        return;

    if (!rect.isEmpty()) {
        OwnPtr<GraphicsContext> context = GraphicsContext::deprecatedCreateWithCanvas(canvas);
        float scaleFactor = m_client->deviceScaleFactor();
        context->scale(scaleFactor, scaleFactor);
        m_widget->paint(context.get(), rect);
    }
}
예제 #14
0
void WebListBox::FitSelection(void)
{
	if (UseVScroll())
	{
		DISPLAY_INT offsetX, offsetY;
		WebRect r;

		GetScrollOffset(&offsetX, &offsetY);
		GetOptionsRect(&r);

		int pos = miSelected * (miTextHeight + GetSpacing());
		if (pos < offsetY)
		{
			mpVScroll->SetPosition(pos);
		}
		else if (pos > offsetY + r.Height() - miTextHeight - GetSpacing())
		{
			mpVScroll->SetPosition(pos - r.Height() + miTextHeight + GetSpacing());
		}
	}
}
예제 #15
0
void WebViewHost::updatePaintRect(const WebRect& rect)
{
    // m_paintRect = m_paintRect U rect
    if (rect.isEmpty())
        return;
    if (m_paintRect.isEmpty()) {
        m_paintRect = rect;
        return;
    }
    int left = min(m_paintRect.x, rect.x);
    int top = min(m_paintRect.y, rect.y);
    int right = max(m_paintRect.x + m_paintRect.width, rect.x + rect.width);
    int bottom = max(m_paintRect.y + m_paintRect.height, rect.y + rect.height);
    m_paintRect = WebRect(left, top, right - left, bottom - top);
}
예제 #16
0
void PageWidgetDelegate::paint(Page* page, PageOverlayList* overlays, WebCanvas* canvas, const WebRect& rect, CanvasBackground background)
{
    if (rect.isEmpty())
        return;
    GraphicsContextBuilder builder(canvas);
    GraphicsContext& gc = builder.context();
    gc.platformContext()->setDrawingToImageBuffer(background == Opaque ? false : true);
    gc.applyDeviceScaleFactor(page->deviceScaleFactor());
    IntRect dirtyRect(rect);
    gc.save();
    FrameView* view = mainFrameView(page);
    // FIXME: Can we remove the mainFrame()->document() check?
    if (view && page->mainFrame()->document()) {
        gc.clip(dirtyRect);
        view->paint(&gc, dirtyRect);
        if (overlays)
            overlays->paintWebFrame(gc);
    } else
        gc.fillRect(dirtyRect, Color::white, ColorSpaceDeviceRGB);
    gc.restore();
}
예제 #17
0
void PageWidgetDelegate::paint(Page* page, PageOverlayList* overlays, WebCanvas* canvas, const WebRect& rect, CanvasBackground background)
{
    if (rect.isEmpty())
        return;
    GraphicsContext gc(canvas);
    gc.setCertainlyOpaque(background == Opaque);
    gc.applyDeviceScaleFactor(page->deviceScaleFactor());
    gc.setUseHighResMarkers(page->deviceScaleFactor() > 1.5f);
    IntRect dirtyRect(rect);
    gc.save(); // Needed to save the canvas, not the GraphicsContext.
    FrameView* view = mainFrameView(page);
    // FIXME: Can we remove the mainFrame()->document() check?
    if (view && page->mainFrame()->document()) {
        gc.clip(dirtyRect);
        view->paint(&gc, dirtyRect);
        if (overlays)
            overlays->paintWebFrame(gc);
    } else {
        gc.fillRect(dirtyRect, Color::white);
    }
    gc.restore();
}
예제 #18
0
void PageWidgetDelegate::paint(Page& page, PageOverlayList* overlays, WebCanvas* canvas, const WebRect& rect, CanvasBackground background, LocalFrame& root)
{
    if (rect.isEmpty())
        return;
    GraphicsContext gc(canvas, nullptr);
    gc.setCertainlyOpaque(background == Opaque);
    float scaleFactor = page.deviceScaleFactor();
    gc.scale(scaleFactor, scaleFactor);
    gc.setDeviceScaleFactor(scaleFactor);
    IntRect dirtyRect(rect);
    gc.save(); // Needed to save the canvas, not the GraphicsContext.
    FrameView* view = root.view();
    if (view) {
        gc.clip(dirtyRect);
        view->paint(&gc, dirtyRect);
        if (overlays)
            overlays->paintWebFrame(gc);
    } else {
        gc.fillRect(dirtyRect, Color::white);
    }
    gc.restore();
}
예제 #19
0
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);
	}
 }
예제 #20
0
void TestShell::dump()
{
    WebScriptController::flushConsoleMessages();

    // Dump the requested representation.
    WebFrame* frame = m_webView->mainFrame();
    if (!frame)
        return;
    bool shouldDumpAsText = m_layoutTestController->shouldDumpAsText();
    bool shouldDumpAsAudio = m_layoutTestController->shouldDumpAsAudio();
    bool shouldGeneratePixelResults = m_layoutTestController->shouldGeneratePixelResults();
    bool shouldDumpAsPrinted = m_layoutTestController->isPrinting();
    bool dumpedAnything = false;

    if (shouldDumpAsAudio) {
        m_printer->handleAudioHeader();

        const WebKit::WebArrayBufferView& webArrayBufferView = m_layoutTestController->audioData();
        printf("Content-Length: %d\n", webArrayBufferView.byteLength());

        if (fwrite(webArrayBufferView.baseAddress(), 1, webArrayBufferView.byteLength(), stdout) != webArrayBufferView.byteLength())
            FATAL("Short write to stdout, disk full?\n");
        printf("\n");

        m_printer->handleTestFooter(true);

        fflush(stdout);
        fflush(stderr);
        return;
    }

    if (m_params.dumpTree) {
        dumpedAnything = true;
        m_printer->handleTextHeader();
        // Text output: the test page can request different types of output
        // which we handle here.
        if (!shouldDumpAsText) {
            // Plain text pages should be dumped as text
            string mimeType = frame->dataSource()->response().mimeType().utf8();
            if (mimeType == "text/plain") {
                shouldDumpAsText = true;
                shouldGeneratePixelResults = false;
            }
        }
        if (shouldDumpAsText) {
            bool recursive = m_layoutTestController->shouldDumpChildFramesAsText();
            string dataUtf8 = shouldDumpAsPrinted ? dumpFramesAsPrintedText(frame, recursive) : dumpFramesAsText(frame, recursive);
            if (fwrite(dataUtf8.c_str(), 1, dataUtf8.size(), stdout) != dataUtf8.size())
                FATAL("Short write to stdout, disk full?\n");
        } else {
          WebFrame::RenderAsTextControls renderTextBehavior = WebFrame::RenderAsTextNormal;
            if (shouldDumpAsPrinted)
                renderTextBehavior |= WebFrame::RenderAsTextPrinting;
            if (m_params.debugRenderTree)
                renderTextBehavior |= WebFrame::RenderAsTextDebug;
            printf("%s", frame->renderTreeAsText(renderTextBehavior).utf8().data());
            bool recursive = m_layoutTestController->shouldDumpChildFrameScrollPositions();
            dumpFrameScrollPosition(frame, recursive);
        }
        if (m_layoutTestController->shouldDumpBackForwardList())
            printf("%s", dumpAllBackForwardLists().c_str());
    }
    if (dumpedAnything && m_params.printSeparators)
        m_printer->handleTextFooter();

    if (m_params.dumpPixels && shouldGeneratePixelResults) {
        // Image output: we write the image data to the file given on the
        // command line (for the dump pixels argument), and the MD5 sum to
        // stdout.
        dumpedAnything = true;
        m_webView->layout();
        if (m_layoutTestController->testRepaint()) {
            WebSize viewSize = m_webView->size();
            int width = viewSize.width;
            int height = viewSize.height;
            if (m_layoutTestController->sweepHorizontally()) {
                for (WebRect column(0, 0, 1, height); column.x < width; column.x++)
                    m_webViewHost->paintRect(column);
            } else {
                for (WebRect line(0, 0, width, 1); line.y < height; line.y++)
                    m_webViewHost->paintRect(line);
            }
        } else if (m_layoutTestController->isPrinting())
            m_webViewHost->paintPagesWithBoundaries();
        else
            m_webViewHost->paintInvalidatedRegion();

        // See if we need to draw the selection bounds rect. Selection bounds
        // rect is the rect enclosing the (possibly transformed) selection.
        // The rect should be drawn after everything is laid out and painted.
        if (m_layoutTestController->shouldDumpSelectionRect()) {
            // If there is a selection rect - draw a red 1px border enclosing rect
            WebRect wr = frame->selectionBoundsRect();
            if (!wr.isEmpty()) {
                // Render a red rectangle bounding selection rect
                SkPaint paint;
                paint.setColor(0xFFFF0000); // Fully opaque red
                paint.setStyle(SkPaint::kStroke_Style);
                paint.setFlags(SkPaint::kAntiAlias_Flag);
                paint.setStrokeWidth(1.0f);
                SkIRect rect; // Bounding rect
                rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height);
                m_webViewHost->canvas()->drawIRect(rect, paint);
            }
        }

        dumpImage(m_webViewHost->canvas());
    }
    m_printer->handleImageFooter();
    m_printer->handleTestFooter(dumpedAnything);
    fflush(stdout);
    fflush(stderr);
}
예제 #21
0
void WebListBox::SetupScrollBars(WebGraphics * gc)
{
	WebRect window;
	GetContentRect(&window);
	DISPLAY_INT w = window.Width();
	DISPLAY_INT h = window.Height();

	WEBC_BOOL needH, needV;
	needH = needV = WEBC_FALSE;

	for (int t = 0; t < 2; t++)
	{
		if (w < GetTotalTextWidth())
		{
			needH = WEBC_TRUE;
			h -= miSliderWidth;
		}
		if (h < GetTotalTextHeight())
		{
			needV = WEBC_TRUE;
			w -= miSliderWidth;
		}
	}

	if (needH && !mpHScroll)
	{
		WEBC_NEW_VERBOSE(mpHScroll, WebHScroll,"wtlist:WebVscroll");
		if (mpHScroll)
		{
			mpHScroll->SetListener(this);
			mpHScroll->SetRange(GetTotalTextWidth());
			mpHScroll->SetStep(miTextHeight);
			mpHScroll->SetPosition(0);
			if (mFlags & DISPLAY_FLAG_DISABLED)
			{
				mpHScroll->Disable();
			}
			InsertLast(mpHScroll);
			ResizeScrollBars();
		}
	}
	else if (!needH && mpHScroll)
	{
		Remove(mpHScroll);
		WEBC_DELETE(mpHScroll);
		mpHScroll = WEBC_NULL;
	}

	if (needV && !mpVScroll)
	{
		WEBC_NEW_VERBOSE(mpVScroll, WebVScroll,"Wtlist:WebVscroll");
		if (mpVScroll)
		{
			mpVScroll->SetListener(this);
			mpVScroll->SetRange(GetTotalTextHeight());
			mpVScroll->SetStep(miTextHeight + GetSpacing());
			mpVScroll->SetPosition(0);
			if (mFlags & DISPLAY_FLAG_DISABLED)
			{
				mpVScroll->Disable();
			}
			InsertLast(mpVScroll);
			ResizeScrollBars();
		}
	}
	else if (!needV && mpVScroll)
	{
		Remove(mpVScroll);
		WEBC_DELETE(mpVScroll);
		mpVScroll = WEBC_NULL;
	}

}
예제 #22
0
/*---------------------------------------------------------------------------*/
template<class T> IPositionedFormatContext* HTMLElementDisplay<T>::FormatSelfPositioned (
		DisplayElement* displayParent,
		IPositionedFormatContext* rootContext,
		IPositionedFormatContext* parentContext,
		FormatContextFactory* childContextFactory,
		WEBC_BOOL generateChildContext
	)
{
	WebRect rect;
	WEBC_UINT16 position = GetPosition();
	IPositionedFormatContext* childContext = 0;

	if (position == TU_POSITION_RELATIVE)
	{
		if (generateChildContext)
		{
			const WebRect * tmpRect = 	&(((DisplayElement *)(this))->mRect);
			rect.Set(tmpRect);
			rect.MoveTo(0,0);

			CSSLength height;
			GetCSSLength(&height, CSS_PROPERTY_HEIGHT);

			childContext = childContextFactory->newPositioned (
					&rect,
					(height.type == CSS_LENGTH_UNIT_AUTO) ||
					(height.type == CSS_LENGTH_UNIT_PERCENT && parentContext->parentHeightIsAuto()), // parent height is auto
					TU_DIR_LTR,
					0, // border-left-width
					0, // border-top-width
					0, // border-right-width
					0, // border-bottom-width
					0, // autoIndentLeft
					0, // autoIndentTop
					0  // autoIndentRight
				);
		}
	}
	else
	{
		WebRect containingBlock;
		IPositionedFormatContext* containingContext;
		DISPLAY_INT borderLeftValue;
		DISPLAY_INT borderTopValue;
		DISPLAY_INT borderRightValue;
		DISPLAY_INT borderBottomValue;

		if (displayParent)
		{
			if (displayParent != T::mpParent)
			{
				mHtmlElementDisplayFlags &= ~HELEM_DISPLAY_FLAG_STYLE_SET;
			}
			displayParent->InsertOrdered(this);
		}

		if (position == TU_POSITION_FIXED)
		{
			T::SetFixedPosition(WEBC_TRUE);
			containingContext = rootContext;
		}
		else
		{
			T::SetFixedPosition(WEBC_FALSE);
			containingContext = parentContext;
		}

		containingContext->getContainingBlock(&containingBlock);

		WEBC_BOOL   parentHeightIsAuto = containingContext->parentHeightIsAuto();
		int         textDirection      = containingContext->getTextDirection();
		DISPLAY_INT parentBorderLeft   = containingContext->getParentBorderLeft();
		DISPLAY_INT parentBorderTop    = containingContext->getParentBorderTop();
		DISPLAY_INT parentBorderRight  = containingContext->getParentBorderRight();
		DISPLAY_INT parentBorderBottom = containingContext->getParentBorderBottom();

		DISPLAY_INT autoIndentLeft     = parentContext->getAutoIndentLeft();
		DISPLAY_INT autoIndentTop      = parentContext->getAutoIndentTop();
		DISPLAY_INT autoIndentRight    = parentContext->getAutoIndentRight();

		if (position == TU_POSITION_FIXED)
		{
			WebRect parentRect;

			parentContext->getContainingBlock(&parentRect);

			autoIndentLeft  += parentRect.left;
			autoIndentTop   += parentRect.top;
			autoIndentRight += (containingBlock.right - parentRect.right);
		}

		DISPLAY_INT parentWidth = containingBlock.Width() - (parentBorderLeft + parentBorderRight);
		DISPLAY_INT parentHeight = containingBlock.Height() - (parentBorderTop + parentBorderBottom);

		WebFont font = mpHtmlElement->GetWebFont();
		DISPLAY_INT emHeight = font? WEB_FONT_HEIGHT(font) : WEBC_CFG_DEFAULT_TEXT_HEIGHT;
		DISPLAY_INT exHeight = emHeight >> 1;

		// First find the left edge and width

		CSSLength left;
		CSSLength right;
		CSSLength width;

		// Find value for left, right, width, marginLeft, marginRight

		GetCSSLength(&left,  CSS_PROPERTY_LEFT);
		GetCSSLength(&right, CSS_PROPERTY_RIGHT);
		GetCSSLength(&width, CSS_PROPERTY_WIDTH);

		DISPLAY_INT leftValue;
		DISPLAY_INT rightValue;
		DISPLAY_INT widthValue;
		DISPLAY_INT marginLeftValue;
		DISPLAY_INT paddingLeftValue;
		DISPLAY_INT paddingTopValue;
		DISPLAY_INT paddingRightValue;
		DISPLAY_INT paddingBottomValue;

		// Find value for padding and border

		paddingLeftValue   = GetPixelLength(CSS_PROPERTY_PADDING_LEFT,   parentWidth, emHeight, exHeight, 0);
		paddingTopValue    = GetPixelLength(CSS_PROPERTY_PADDING_TOP,    parentWidth, emHeight, exHeight, 0);
		paddingRightValue  = GetPixelLength(CSS_PROPERTY_PADDING_RIGHT,  parentWidth, emHeight, exHeight, 0);
		paddingBottomValue = GetPixelLength(CSS_PROPERTY_PADDING_BOTTOM, parentWidth, emHeight, exHeight, 0);

		borderLeftValue    = GetBorderWidth(CSS_LEFT,   parentWidth, emHeight, exHeight, parentBorderLeft);
		borderTopValue     = GetBorderWidth(CSS_TOP,    parentWidth, emHeight, exHeight, parentBorderTop);
		borderRightValue   = GetBorderWidth(CSS_RIGHT,  parentWidth, emHeight, exHeight, parentBorderRight);
		borderBottomValue  = GetBorderWidth(CSS_BOTTOM, parentWidth, emHeight, exHeight, parentBorderBottom);

		CSSLength height;
		CSSLength top;
		CSSLength bottom;
		DISPLAY_INT heightValue=0;
		WEBC_BOOL heightIsAuto=0;

		GetCSSLength(&height, CSS_PROPERTY_HEIGHT);
		GetCSSLength(&top, CSS_PROPERTY_TOP);

#define NOTHING_KNOWN 0
#define HEIGHT_KNOWN  1
#define TOP_KNOWN     2
#define BOTTOM_KNOWN  4

		WEBC_UINT8 verticalCase;

		verticalCase =  (height.type == CSS_LENGTH_UNIT_AUTO ||
		                 (height.type == CSS_LENGTH_UNIT_PERCENT && parentHeightIsAuto))? 0 : HEIGHT_KNOWN;
		verticalCase |= (top.type == CSS_LENGTH_UNIT_AUTO)? 0 : TOP_KNOWN;

		if (verticalCase != (HEIGHT_KNOWN|TOP_KNOWN))
		{
			GetCSSLength(&bottom, CSS_PROPERTY_BOTTOM);
			verticalCase |= (bottom.type == CSS_LENGTH_UNIT_AUTO || parentHeightIsAuto)? 0 : BOTTOM_KNOWN;
		}

		DISPLAY_INT topValue = 0;
		DISPLAY_INT bottomValue = 0;
		DISPLAY_INT marginTopValue = 0;
		DISPLAY_INT marginBottomValue = 0;

		switch (verticalCase)
		{
			case NOTHING_KNOWN:
				// top = auto indent top
				// height = content height
				topValue = autoIndentTop;
				heightValue = 0;
				heightIsAuto = WEBC_TRUE;
				marginTopValue = GetPixelLength(CSS_PROPERTY_MARGIN_TOP, parentWidth, emHeight, exHeight, 0);
				break;

			case HEIGHT_KNOWN:
				// top = auto indent top
				// height = height
				topValue = autoIndentTop;
				heightValue = CSS_LengthToPixels(&height, parentHeight, emHeight, exHeight);
				heightIsAuto = WEBC_FALSE;
				marginTopValue = GetPixelLength(CSS_PROPERTY_MARGIN_TOP, parentWidth, emHeight, exHeight, 0);
				break;

			case TOP_KNOWN:
				// top = top
				// height = content height
				if (top.type == CSS_LENGTH_UNIT_PERCENT && parentHeightIsAuto)
				{
					topValue = autoIndentTop;
				}
				else
				{
					topValue = CSS_LengthToPixels(&top, parentHeight, emHeight, exHeight);
				}
				heightValue = 0;
				heightIsAuto = WEBC_TRUE;
				marginTopValue = GetPixelLength(CSS_PROPERTY_MARGIN_TOP, parentWidth, emHeight, exHeight, 0);
				break;

			case HEIGHT_KNOWN|TOP_KNOWN:
				// top = top
				// height = height
				if (top.type == CSS_LENGTH_UNIT_PERCENT && parentHeightIsAuto)
				{
					topValue = autoIndentTop;
				}
				else
				{
					topValue = CSS_LengthToPixels(&top, parentHeight, emHeight, exHeight);
				}
				heightValue = CSS_LengthToPixels(&height, parentHeight, emHeight, exHeight);
				heightIsAuto = WEBC_FALSE;
				marginTopValue = GetPixelLength(CSS_PROPERTY_MARGIN_TOP, parentWidth, emHeight, exHeight, 0);
				break;

			case BOTTOM_KNOWN:
				// bottom = bottom
				// height = content height
				// top = parentHeight - (height + bottom)
				bottomValue = GetPixelLength(&bottom, parentHeight, emHeight, exHeight, 0);
				marginBottomValue = GetPixelLength(CSS_PROPERTY_MARGIN_BOTTOM, parentWidth, emHeight, exHeight, 0);
				heightValue = 0;
				heightIsAuto = WEBC_TRUE;
				break;

			case HEIGHT_KNOWN|BOTTOM_KNOWN:
				// bottom = bottom
				// height = height
				// top = parentHeight - (height + bottom)
				bottomValue = GetPixelLength(&bottom, parentHeight, emHeight, exHeight, 0);
				heightValue = CSS_LengthToPixels(&height, parentHeight, emHeight, exHeight);
				heightIsAuto = WEBC_FALSE;

				marginBottomValue = GetPixelLength(CSS_PROPERTY_MARGIN_BOTTOM, parentWidth, emHeight, exHeight, 0);

				topValue = parentHeight -
			               (borderTopValue +
			                paddingTopValue +
			                heightValue +
			                paddingBottomValue +
			                borderBottomValue +
			                marginBottomValue +
			                bottomValue);
				break;

			case TOP_KNOWN|BOTTOM_KNOWN:
				// top = top
				// bottom = bottom
				// height = parentHeight - (top + bottom)
				if (top.type == CSS_LENGTH_UNIT_PERCENT && parentHeightIsAuto)
				{
					topValue = autoIndentTop;
				}
				else
				{
					topValue = CSS_LengthToPixels(&top, parentHeight, emHeight, exHeight);
				}
				bottomValue = GetPixelLength(&bottom, parentHeight, emHeight, exHeight, 0);

				marginTopValue = GetPixelLength(CSS_PROPERTY_MARGIN_TOP, parentWidth, emHeight, exHeight, 0);
				marginBottomValue = GetPixelLength(CSS_PROPERTY_MARGIN_BOTTOM, parentWidth, emHeight, exHeight, 0);

				heightValue = parentHeight -
				              (topValue +
							   marginTopValue +
							   borderTopValue +
							   paddingTopValue +
				               paddingBottomValue +
							   borderBottomValue +
							   marginBottomValue +
							   bottomValue);
				heightIsAuto = WEBC_FALSE;
				break;
		}

		if (width.type != CSS_LENGTH_UNIT_AUTO)
		{
			widthValue = CSS_LengthToPixels(&width, parentWidth, emHeight, exHeight);

			WEBC_BOOL leftAligned = (textDirection == TU_DIR_RTL)?
			                            (right.type == CSS_LENGTH_UNIT_AUTO && left.type  != CSS_LENGTH_UNIT_AUTO) :
										(left.type  != CSS_LENGTH_UNIT_AUTO || right.type == CSS_LENGTH_UNIT_AUTO);

			if (leftAligned)
			{
				// ignore right and margin-right
				leftValue = GetPixelLength(&left, parentWidth, emHeight, exHeight, autoIndentLeft);
				marginLeftValue = GetPixelLength(CSS_PROPERTY_MARGIN_LEFT, parentWidth, emHeight, exHeight, 0);
			}
			else
			{
				DISPLAY_INT marginRightValue;

				// ignore left and margin-left
				rightValue = GetPixelLength(&right, parentWidth, emHeight, exHeight, autoIndentRight);
				marginRightValue = GetPixelLength(CSS_PROPERTY_MARGIN_RIGHT, parentWidth, emHeight, exHeight, 0);
				leftValue = parentWidth -
				            (rightValue +
							 marginRightValue +
							 borderRightValue +
							 paddingRightValue +
				             widthValue +
							 paddingLeftValue +
							 borderLeftValue);

				marginLeftValue = 0;
			}
		}
		else
		{
			// width.type == CSS_LENGTH_UNIT_AUTO

			// try to get the intrinsic width of the element.  This might rely on the
			//  calculated height of the element; for example, in the case of an image with
			//  specified height and auto width, the aspect ratio of the source image determines
			//  the resulting intrinsic width.

			DISPLAY_INT marginRightValue;
			WEBC_BOOL hasIntrinsicWidth = GetIntrinsicWidth(&widthValue, heightValue, heightIsAuto);

			if (left.type == CSS_LENGTH_UNIT_AUTO && right.type != CSS_LENGTH_UNIT_AUTO && hasIntrinsicWidth)
			{
				rightValue = GetPixelLength(&right, parentWidth, emHeight, exHeight, autoIndentRight);
				marginRightValue = GetPixelLength(CSS_PROPERTY_MARGIN_RIGHT, parentWidth, emHeight, exHeight, 0);
				marginLeftValue = 0;

				leftValue = parentWidth -
							 (widthValue +
							  borderLeftValue +
							  paddingLeftValue +
							  paddingRightValue +
							  borderRightValue +
							  marginRightValue +
							  rightValue);
			}
			else
			{
				leftValue = GetPixelLength(&left,  parentWidth, emHeight, exHeight, autoIndentLeft);
				marginLeftValue = GetPixelLength(CSS_PROPERTY_MARGIN_LEFT,  parentWidth, emHeight, exHeight, 0);

				if (!hasIntrinsicWidth || (right.type != CSS_LENGTH_UNIT_AUTO && left.type != CSS_LENGTH_UNIT_AUTO))
				{
					// right and left are both non-auto, OR element has no intrinsic width:
					//  calculate left, right, and margins then extrapolate width
					rightValue = GetPixelLength(&right, parentWidth, emHeight, exHeight, autoIndentRight);
					marginRightValue = GetPixelLength(CSS_PROPERTY_MARGIN_RIGHT, parentWidth, emHeight, exHeight, 0);

					widthValue = parentWidth -
								 (leftValue +
								  marginLeftValue +
								  borderLeftValue +
								  paddingLeftValue +
								  paddingRightValue +
								  borderRightValue +
								  marginRightValue +
								  rightValue);

					// we don't want to stretch the width beyond what the maximum content
					//  width; only give the element as much space as it actually needs.
					if (right.type == CSS_LENGTH_UNIT_AUTO || left.type == CSS_LENGTH_UNIT_AUTO)
					{
						// to speed this up, bail out of GetMaxWidth when we exceed widthValue
						DISPLAY_INT maxWidth = GetMaxWidthSmallerThan(widthValue);

						// NOTE: GetMaxWidth and GetMaxWidthSmallerThan return the total width
						//  of the element, including borders and padding.  So we must subtract
						//  borders and padding to make it correspond to the contentWidth

						maxWidth -= (borderLeftValue + paddingLeftValue + paddingRightValue + borderRightValue);

						if (maxWidth < widthValue)
						{
							WEBC_BOOL leftAligned = (textDirection == TU_DIR_RTL)?
														(right.type == CSS_LENGTH_UNIT_AUTO && left.type  != CSS_LENGTH_UNIT_AUTO) :
														(left.type  != CSS_LENGTH_UNIT_AUTO || right.type == CSS_LENGTH_UNIT_AUTO);

							if (!leftAligned)
							{
								// box is right-aligned
								//  adjust leftValue to account for the unused space
								leftValue += (widthValue - maxWidth);
							}
							widthValue = maxWidth;
						}
					}
				}
			}
		}

		// Now format the content of this element

		DISPLAY_INT contentHeight = FormatContentPositioned (
				widthValue,
				heightValue,
				heightIsAuto,
				borderLeftValue,
				borderTopValue,
				borderRightValue,
				borderBottomValue,
				paddingLeftValue,
				paddingTopValue,
				paddingRightValue,
				paddingBottomValue
			);

		// Find the top edge and height

		//  NOTE: top and bottom percentages are relative to parent's HEIGHT, whereas
		//   margin-top and margin-bottom are relative to parent's WIDTH, except in the root
		//   context (tbd - handle this special case correctly)

		switch (verticalCase)
		{
			case NOTHING_KNOWN:
			case TOP_KNOWN:
				heightValue = contentHeight;
				break;

			case BOTTOM_KNOWN:
				// height = content height
				// top = parentHeight - (height + bottom)
				heightValue = contentHeight;
				topValue = parentHeight -
			               (borderTopValue +
			                paddingTopValue +
			                heightValue +
			                paddingBottomValue +
			                borderBottomValue +
			                marginBottomValue +
			                bottomValue);
				break;
		}

		rect.Set (0, 0,
				borderLeftValue + paddingLeftValue + widthValue  + paddingRightValue  + borderRightValue - 1,
				borderTopValue  + paddingTopValue  + heightValue + paddingBottomValue + borderBottomValue - 1
			);

		rect.MoveTo (
				parentBorderLeft + leftValue + marginLeftValue,
				parentBorderTop + topValue  + marginTopValue
			);

		if (position == TU_POSITION_FIXED)
		{
			rect.Shift(containingBlock.left, containingBlock.top);
		}

		Move(&rect);

		if (generateChildContext)
		{
			childContext = childContextFactory->newPositioned (
					&rect,
					heightIsAuto,
					TU_DIR_LTR,
					borderLeftValue,
					borderTopValue,
					borderRightValue,
					borderBottomValue,
					paddingLeftValue,
					paddingTopValue,
					paddingRightValue
				);
		}
	}

	return (childContext);
}
예제 #23
0
void WebEditBox::Format (void)
{
	WebGraphics *gc = GetGraphics();
	WebFont font = mFont.GetFont();

	if (!gc || !mpText || !font)
	{
		return;
	}

	int i = 0;
	do
	{
		long iIndex = 0;
		long iNextWord;
		DISPLAY_INT iWidthUsed = 0;
		WebRect box;
		DISPLAY_INT iWordWidth;

		GetTextRect(&box);
		DISPLAY_INT iWidthAvailable = box.Width();
//printf("Box w == %d\n",iWidthAvailable);
		miMaxLineWidth = 0;
		miNumLines = 1;
		while (mpText[iIndex])
		{
			switch (mpText[iIndex])
			{
				case (WebChar) '\r':
				case (WebChar) '\n':
					// break the line at CR/LF
					AddLine(++iIndex);
					iWidthUsed = 0;
					break;

				default:
					if (!(mEditFlags & EDIT_FLAG_WRAP))
					{
						iWordWidth = gc->TextWidthLen(&mpText[iIndex], font, 1);
						iWidthUsed += iWordWidth;
						miMaxLineWidth = EBSMAX(miMaxLineWidth, iWidthUsed);
						iIndex++;
					}
					else
					{

#if (TEXT_BOX_SCROLL_DISABLED)
					WebChar mpText1='m';
					DISPLAY_INT charWidth = gc->TextWidthLen(&mpText[iIndex], font, 1);
					if (iWidthUsed + charWidth > (iWidthAvailable) && iWidthUsed > 0)
					{
						AddLine(iIndex);
						iWidthUsed = charWidth;
						miMaxLineWidth = EBSMAX(miMaxLineWidth, charWidth);
						iIndex++;
					}
					else
					{
						iIndex++;
						iWidthUsed += charWidth;
					}
				}//switch statement
#else
						if (IS_WHITESPACE(mpText[iIndex]))
						{

							iWidthUsed += gc->TextWidthLen(&mpText[iIndex++], font, 1);
						}
						else
						{

							iNextWord = iIndex;
							while (!IS_WHITESPACE(mpText[iNextWord]) && mpText[iNextWord])
							{
								iNextWord++;
							}
							iWordWidth = gc->TextWidthLen(&mpText[iIndex], font, iNextWord-iIndex);
							// only do a line break if there is something already on the line
							if (iWidthUsed + iWordWidth > iWidthAvailable && iWidthUsed > 0)
							{
								// the next word_ will not fit; break the line.
								AddLine(iIndex);
								iWidthUsed = iWordWidth;
								miMaxLineWidth = EBSMAX(miMaxLineWidth, iWordWidth);
								iIndex = iNextWord;
							}
							else
							{
								// the next word_ will fit on this line
								iWidthUsed += iWordWidth;
								miMaxLineWidth = EBSMAX(miMaxLineWidth, iWordWidth);
								iIndex = iNextWord;
							}
						}
					}
#endif
					break;
			}
		}

		i++;
	}
예제 #24
0
void WebEditBox::DrawThisOnly (DISPLAY_INT x, DISPLAY_INT y, WebGraphics *gc)
{
	WebChar c;
	long line;

	WebRect box;
	GetFrameRect(&box);
	box.Shift(x,y);

//	gc->StartBuffer();                      // begin buffering graphics commands
	gc->Rectangle(&box, GetBgColor(gc), GetBgColor(gc), 1);	// draw background
	DrawFrame(&box, gc);

	// save the current graphics context clip rectangle and set clipping to the
	//  text display region of the widget
	GetTextRect(&box);
	box.Shift(x,y);
	WebRect clipSave;
	gc->GetClip(&clipSave);
	if (clipSave.Overlaps(&box))
	{
		WebRect clip(box);
		clip.And(&clipSave);
		gc->SetClip(&clip);

		miXOffset = (mpHScroll)? mpHScroll->GetPosition() : 0;
		miYOffset = (mpVScroll)? mpVScroll->GetPosition() : 0;

		// render our text
		WebFont font = mFont.GetFont();
		if (mpText && font)
		{
			// this loop draws up to the last line
			for (line=0; line<(miNumLines-1); line++)
			{
				c = mpText[GetLineOffset(line+1)];
				mpText[GetLineOffset(line+1)] = 0;
				DrawText(gc, box.left - miXOffset, box.top - miYOffset + (line * WEB_FONT_HEIGHT(font)),
				         mpText + GetLineOffset(line), GetTextColor(gc), 0, 0, font);
				mpText[GetLineOffset(line+1)] = c;
			}

			// now draw the last line of text.
			DrawText(gc, box.left - miXOffset, box.top - miYOffset + (line*WEB_FONT_HEIGHT(font)),
			         mpText + GetLineOffset(line), GetTextColor(gc), 0, 0, font);

			// if we have the focus, draw the cursor
			if ((mFlags & DISPLAY_FLAG_FOCUS) && !(mFlags & DISPLAY_FLAG_DISABLED))
			{
				// now render the selected portion in reverse video (if we have one)
				if (mEditFlags & EDIT_FLAG_HAS_SELECTION)
				{
					long begin = EBSMIN(miCursorPos, miSelectBegin);
					long end = EBSMAX(miCursorPos, miSelectBegin);
					long beginLine = FindLine(begin), endLine = FindLine(end);
					DISPLAY_INT textLeft;
					long currentBegin, currentEnd;

					for (line=beginLine; line<=endLine; line++)
					{
						currentBegin = EBSMAX(begin, GetLineOffset(line));
						if (line == endLine)
						{
							currentEnd = end;
						}
						else
						{
							currentEnd = EBSMIN(end, GetLineOffset(line+1));
						}
						textLeft = gc->TextWidthLen(mpText + GetLineOffset(line), font, EBSMAX(0, begin - GetLineOffset(line)));

						c = mpText[currentEnd];
						mpText[currentEnd] = 0;
						DrawText(gc, box.left - miXOffset + textLeft,
						             box.top - miYOffset + (line*WEB_FONT_HEIGHT(font)),
						             mpText + currentBegin, GetBgColor(gc), GetSelectColor(gc), 1, font);
						mpText[currentEnd] = c;
					}
				}

				DISPLAY_INT cursorX = box.left - miXOffset +
					gc->TextWidthLen(mpText + GetLineOffset(miCurrentLine), font, miCursorPos - GetLineOffset(miCurrentLine)) ;
				box.Set(cursorX, box.top - miYOffset + WEB_FONT_HEIGHT(font)*miCurrentLine,
				        cursorX, box.top - miYOffset + WEB_FONT_HEIGHT(font)*(miCurrentLine+1));
				gc->Rectangle(&box, GetSelectColor(gc), GetSelectColor(gc), 1);
			}

		}

		gc->SetClip(&clipSave);	 // restore the clip rectangle
	} // if clip overlaps

/*	if (mpVScroll && mpHScroll)
	{
		GetCornerRect(&box);
		box.Shift(x,y);
		gc->Rectangle(&box, LIGHTGRAY, LIGHTGRAY, 1);
	}*/

//	gc->EndBuffer();	     // send all buffered commands to the display

}
예제 #25
0
// x,y are in same coordinate space as this->mRect; viewX, viewY is the upper left corner of the viewport in
//  the coordinate space of this->mRect
DisplayElement *DisplayElement::TrapEventPoint (DISPLAY_INT x, DISPLAY_INT y, DISPLAY_INT viewX, DISPLAY_INT viewY)
{
	// if we clip our children to our rect, and the point is outside our rect,
	//  then fail right away
	if (GetOverflow() == DISPLAY_OVERFLOW_HIDDEN)
	{
		WebRect clipRect;
		GetClipRect(&clipRect);
		if (!clipRect.Contains(x,y))
		{
			return (0);
		}
	}

	DisplayElement *pChild = mpLastChild, *pFound;

	// now search positive-z children in reverse order
	while (pChild && (pChild->GetZIndex() >= 0))
	{
		if (pChild->mFlags & DISPLAY_FLAG_FIXED_POS)
		{
			pFound = pChild->TrapEventPoint(x - (mRect.left + viewX), y - (mRect.top + viewY), -mRect.left, -mRect.top);
		}
		else
		{
			pFound = pChild->TrapEventPoint(x - mRect.left, y - mRect.top, viewX - mRect.left, viewY - mRect.top);
		}

		if (pFound)
		{
			return (pFound);
		}
		pChild = pChild->mpPrev;
	}

	// if we contain the point, trap it
	if (TrapEventInThis(x,y))
	{
		return (this);
	}

	// now search negative-z children in reverse order
	while (pChild)
	{
		if (pChild->mFlags & DISPLAY_FLAG_FIXED_POS)
		{
			pFound = pChild->TrapEventPoint(x - (mRect.left + viewX), y - (mRect.top + viewY), -mRect.left, -mRect.top);
		}
		else
		{
			pFound = pChild->TrapEventPoint(x - mRect.left, y - mRect.top, viewX - mRect.left, viewY - mRect.top);
		}

		if (pFound)
		{
			return (pFound);
		}
		pChild = pChild->mpPrev;
	}

	return (0);
}
예제 #26
0
void DisplayElement::Draw (DISPLAY_INT iScreenX, DISPLAY_INT iScreenY, WebRect *pViewport, WebGraphics *pGC)
{
	DisplayElement *pChild = mpFirstChild;
	WebRect clip, saveClip, screenClip;
	WEBC_BOOL clipRestore = WEBC_FALSE;

	pGC->GetClip(&saveClip);
	clip.Set(&saveClip);
	if (GetOverflow() != DISPLAY_OVERFLOW_VISIBLE)
	//if (GetOverflow() == DISPLAY_OVERFLOW_HIDDEN)
	{
		GetClipRect(&screenClip);
		screenClip.Shift(iScreenX - mRect.left, iScreenY - mRect.top);
		if (!clip.Overlaps(&screenClip))
		{
			// we're not visible, so neither are our children
			return;
		}
		clip.And(&screenClip);
		pGC->SetClip(&clip);
		clipRestore = WEBC_TRUE;
	}

	WebRect screenRect(mRect);
	screenRect.MoveTo(iScreenX, iScreenY);
	mScreenRect = screenRect; // April2013 - save the screenrect of last known draw and subtract boundaries of the display manager screenrect
	DisplayManager*pManager= this->GetManager();
	if (pManager && pManager->mBrowser)
		pManager=pManager->mBrowser->GetDisplayManager();
	if (pManager)
	{
	WebRect r;
//	printf("Not working all the way \n");
		r=pManager->mScreenRect;
		mScreenRect.top -= r.top;
		mScreenRect.bottom -= r.top;
		mScreenRect.left -= r.left;
		mScreenRect.right -= r.left;
	}  // April2013 - end save the screenrect of last known draw and subtract boundaries of the display manager screenrect
	// Start drawing
//	pGC->StartBuffer();

	// Draw negative-z children
	while (pChild && (pChild->GetZIndex() < 0))
	{
		if (pChild->mFlags & DISPLAY_FLAG_FIXED_POS)
		{
			pChild->Draw(pViewport->left + pChild->mRect.left, pViewport->top + pChild->mRect.top, pViewport, pGC);
		}
		else
		{
			pChild->Draw(iScreenX + pChild->mRect.left, iScreenY + pChild->mRect.top, pViewport, pGC);
		}
		pChild = pChild->mpNext;
	}

	// if I am visible
	if (screenRect.Overlaps(&clip))
	{
		// Draw myself
		DrawThisOnly(iScreenX, iScreenY, pGC);
	}
#if (INCLUDE_EXPERIMENTAL_DIV_SCROLLBARS)
	int xContentOffset=0;
	int yContentOffset=0;

	if (clipRestore && vScrollWidth() || hScrollWidth())
	{
		WebRect contentClip;
		contentClip.Set(&clip);
		contentClip.SetHeight(contentClip.Height()-hScrollWidth());
		contentClip.SetWidth(contentClip.Width()-vScrollWidth());
		pGC->SetClip(&contentClip);

		if (GetHScroll())
		{
			WebHScroll *pScroll = (WebHScroll *)GetHScroll();
			xContentOffset=pScroll->GetPosition();
		}
		if (GetVScroll())
		{
			WebVScroll *pScroll = (WebVScroll *)GetVScroll();
			yContentOffset=pScroll->GetPosition();
			if (yContentOffset)
			{ // If we have a y offset step i nto the content holder element
			  // so we don't exclude the whole thing becuase it is out of our
			  // range.
		//		if (GetInlineContentHolder())
		//			pChild = GetInlineContentHolder()->mpFirstChild;
				;
			}
		}
	}
#endif

	// Draw positive-z children
	while (pChild)
	{
#if (INCLUDE_EXPERIMENTAL_DIV_SCROLLBARS)
		if (pChild->IncludeInFlow() && pChild->mRect.bottom >= yContentOffset && pChild->mRect.right >= xContentOffset)
		{
			if (pChild->mFlags & DISPLAY_FLAG_FIXED_POS)
			{
				pChild->Draw(pViewport->left+pChild->mRect.left-xContentOffset, pViewport->top+pChild->mRect.top-yContentOffset, pViewport, pGC);
			}
			else
			{
				pChild->Draw(iScreenX + pChild->mRect.left-xContentOffset, iScreenY+pChild->mRect.top-yContentOffset, pViewport, pGC);
			}
		}
#else
		if (pChild->mFlags & DISPLAY_FLAG_FIXED_POS)
		{
			pChild->Draw(pViewport->left + pChild->mRect.left, pViewport->top + pChild->mRect.top, pViewport, pGC);
		}
		else
		{
			pChild->Draw(iScreenX + pChild->mRect.left, iScreenY + pChild->mRect.top, pViewport, pGC);
		}
#endif
		pChild = pChild->mpNext;
	}


	if (clipRestore)
	{
		pGC->SetClip(&saveClip);
	}
#if (INCLUDE_EXPERIMENTAL_DIV_SCROLLBARS)
	if (clipRestore && vScrollWidth() || hScrollWidth())
	{
		DisplayElement *pScroll;
		if (GetHScroll())
		{
			pScroll = (WebHScroll *)GetHScroll();
			pScroll->Draw(iScreenX + pScroll->mRect.left, iScreenY + pScroll->mRect.top, pViewport, pGC);
		}
		if (GetVScroll())
		{
			pScroll = (WebVScroll *)GetVScroll();
			pScroll->Draw(iScreenX + pScroll->mRect.left, iScreenY + pScroll->mRect.top, pViewport, pGC);
		}
		pGC->SetClip(&saveClip);
	}
#endif
//	pGC->EndBuffer();
}
예제 #27
0
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 (&copyFrom);

					copyTo.ShiftOver(mViewRect.Width());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftDown(mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftOver(-mViewRect.Width());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);
				}

				if (bufferDirty.Overlaps(&northeast))
				{
					PresetWebRect copyFrom (&bufferDirty);
					copyFrom.And(&northeast);

					PresetWebRect copyTo (&copyFrom);

					copyTo.ShiftDown(mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftOver(-mViewRect.Width());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftDown(-mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);
				}

				if (bufferDirty.Overlaps(&southeast))
				{
					PresetWebRect copyFrom (&bufferDirty);
					copyFrom.And(&southeast);

					PresetWebRect copyTo (&copyFrom);

					copyTo.ShiftDown(-mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftOver(-mViewRect.Width());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftDown(mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);
				}

				if (bufferDirty.Overlaps(&southwest))
				{
					PresetWebRect copyFrom (&bufferDirty);
					copyFrom.And(&southwest);

					PresetWebRect copyTo (&copyFrom);

					copyTo.ShiftDown(-mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftOver(mViewRect.Width());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftDown(mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, 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);
		}
	}
}
예제 #28
0
void DisplayManager::SetViewport (WebRect *pViewRect)
{
	if (!mViewRect.Equals(pViewRect))
	{
		PresetWebRect oldRect(&mViewRect);

		mViewportChanged = WEBC_TRUE;
		mViewRect.Set(pViewRect);

		CorrectViewportPosition();

	  #ifdef WEBC_BUFFER_SCROLLING
		if (mManagerFlags & MANAGER_FLAG_BUFFER_SCROLL)
		{
			WebGraphics* gc = this->GetGraphics();
			if (gc)
			{
				if (mScrollBuffer == 0)
				{
					mScrollBuffer = gc->CreateBuffer(mViewRect.Width() * 2, mViewRect.Height() * 2);
				}
				else
				{
					if (oldRect.Width() != mViewRect.Width() ||
					    oldRect.Height() != mViewRect.Height())
					{
						mScrollBuffer = gc->ResizeBuffer(mScrollBuffer, mViewRect.Width() * 2, mViewRect.Height() * 2);
						AddDirtyRect(&mViewRect);
						SetManagerFlag(MANAGER_FLAG_DIRTY);
						return;
					}
				}

				if (mScrollBuffer)
				{
					// find non-overlapping regions
					if (mViewRect.Overlaps(&oldRect))
					{
						PresetWebRect viewRect(&mViewRect);
						WebRect extraRect;

						int count = viewRect.Split(&oldRect, &extraRect);
						if (count > 0)
						{
							if (count > 1)
							{
								if (count > 2)
								{
									if (!extraRect.Empty())
									{
										AddDirtyRect(&extraRect);
									}
								}
								if (!oldRect.Empty())
								{
									AddDirtyRect(&oldRect);
								}
							}
							if (!viewRect.Empty())
							{
								AddDirtyRect(&viewRect);
							}
						}
					}
					else
					{
						AddDirtyRect(&mViewRect);
					}

					SetManagerFlag(MANAGER_FLAG_DIRTY);
				}
			}

		}
	  #endif
	}
}
예제 #29
0
void DisplayManager::Draw(DISPLAY_INT x, DISPLAY_INT y, WebRect *pViewport, WebGraphics *pGC)
{
	if (mNoRefresh)
	{
		DisplayManager* parentDisplayManager = GetManager();

		if (parentDisplayManager)
		{
			// This handles the case where a DisplayManager that is NOT the root
			//  DisplayManager has a positive refresh lock, prohibiting its being
			//  drawn, but the parent DisplayManager does not (otherwise we would
			//  not even be in our Draw method); in this case:
			//
			// IF this element is within the collective invalid region being
			//    painted, THEN we want to re-invalidate the invalid part of (this),
			//    which will cause said region to re-paint when the refresh lock
			//    is removed from this element and this->Refresh is eventually called.

			WebRect clipRect;
			pGC->GetClip(&clipRect);

			WebRect screenRect(mRect);
			screenRect.MoveTo(x,y);

			if (clipRect.Overlaps(&screenRect))
			{
				SetManagerFlag(MANAGER_FLAG_TRIED_TO_DRAW);
				//screenRect.And(&clipRect);
				//screenRect.Shift(-pViewport->left, -pViewport->top);
				//parentDisplayManager->InvalidateViewportRegion(&screenRect);
			}
		}

		return;
	}

	FormatResult result;

	switch (GetScrollMode())
	{
		case SCROLL_MODE_NONE:
			if (mpVScroll || mpHScroll)
			{
				DetachVScroll();
				DetachHScroll();
				UpdateViewport();
			}
			break;

		case SCROLL_MODE_HSCROLL:
			if (mpVScroll || !mpHScroll)
			{
				DetachVScroll();
				AttachHScroll();
				UpdateViewport();
			}
			break;

		case SCROLL_MODE_VSCROLL:
			if (!mpVScroll || mpHScroll)
			{
				AttachVScroll();
				DetachHScroll();
				UpdateViewport();
			}
			break;

		case SCROLL_MODE_BOTH:
			if (!mpVScroll || !mpHScroll)
			{
				AttachVScroll();
				AttachHScroll();
				UpdateViewport();
			}
			break;

		case SCROLL_MODE_AUTO:
			break;
	}

	if (mRoot.Get())
	{
		int i = 0;

		do
		{
			result = mRoot.Get()->FormatForViewport(&mViewRect, (mpHScroll != 0), (mpVScroll != 0));

			if (GetScrollMode() == SCROLL_MODE_AUTO)
			{
				if (result == DISPLAY_FORMAT_NEEDS_VSCROLL)
				{
					// create a vscroll bar
					if (mpVScroll)
					{
						// what the... we already have a vscroll bar!
						break;
					}
					AttachVScroll();

					// check for creation failure - may indicate low memory condition
					if (!mpVScroll)
					{
						// can't go on...
						break;
					}

					UpdateViewport();
				}
				else if (result == DISPLAY_FORMAT_NEEDS_HSCROLL)
				{
					// create a hscroll bar
					if (mpHScroll)
					{
						// what the... we already have a hscroll bar!
						break;
					}
					AttachHScroll();

					// check for creation failure - may indicate low memory condition
					if (!mpHScroll)
					{
						// can't go on...
						break;
					}

					UpdateViewport();
				}
			}
			else
			{
				break;
			}

			// put a hard upper bound on the number of times we try to re-format
			//  (4, since this means we've covered all combinations of horizontal
			//   and vertical scroll bars on the window)
			i++;
		}
		while (result != DISPLAY_FORMAT_SUCCESS && i < 5);

		if (GetScrollMode() == SCROLL_MODE_AUTO)
		{
			WebRect rootBounds;
			GetRootBounds(&rootBounds);

			if (rootBounds.Height() <= mViewRect.Height() && mpVScroll)
			{
				DetachVScroll();
				UpdateViewport();
				mRoot.Get()->FormatForViewport(&mViewRect, (mpHScroll != 0), (mpVScroll != 0));
				GetRootBounds(&rootBounds);
			}

			if (rootBounds.Width() <= mViewRect.Width() && mpHScroll)
			{
				DetachHScroll();
				UpdateViewport();
				mRoot.Get()->FormatForViewport(&mViewRect, (mpHScroll != 0), (mpVScroll != 0));
				GetRootBounds(&rootBounds);
			}

			if (rootBounds.Height() <= mViewRect.Height() && mpVScroll)
			{
				DetachVScroll();
				UpdateViewport();
				mRoot.Get()->FormatForViewport(&mViewRect, (mpHScroll != 0), (mpVScroll != 0));
				GetRootBounds(&rootBounds);
			}
		}

		mViewportChanged = WEBC_FALSE;

		CorrectViewportPosition();

		if (mpFocus && (mpVScroll!=0) && (mpHScroll!=0))
		{
			WebRect focusRect;
			WebRect elemRect;
			WEBC_BOOL ensureFocusVisible = mpFocus->GetFocusRect (&focusRect);
			if (ensureFocusVisible)
			{
				GetElementRect(&elemRect, mpFocus);
				focusRect.Shift(elemRect.left, elemRect.top);

				// this will adjust the scroll bars so that the given rect is in view
				EnsureRectVisible(&focusRect);
			}
		}
	}

	DisplayElement::Draw(x, y, pViewport, pGC);
}
예제 #30
0
void DisplayManager::DrawThisOnly (DISPLAY_INT x, DISPLAY_INT y, WebGraphics *gc)
{
	DISPLAY_INT scrollLeft = (mpHScroll)? mpHScroll->GetPosition() : mViewRect.left;
	DISPLAY_INT scrollTop  = (mpVScroll)? mpVScroll->GetPosition() : mViewRect.top;

	mViewRect.MoveTo(scrollLeft, scrollTop);

	WebRect padding;
	GetPaddingWidth(&padding);

	// find our viewport rect in screen coordinates
	WebRect screenRect(mRect);
	screenRect.MoveTo(x,y);

	WebRect screenView(screenRect);
	screenView.Shift(padding.left, padding.top);
	screenView.SizeTo(mViewRect.Width(), mViewRect.Height());

	WebRect saveClip;
	gc->GetClip(&saveClip);

	WebRect screenDirty(screenView);
	if (saveClip.Overlaps(&screenDirty))
	{
		screenDirty.And(&saveClip);

	  #ifdef WEBC_BUFFER_SCROLLING

		if ((GetManagerFlags() & MANAGER_FLAG_BUFFER_SCROLL) &&
		    mScrollBuffer)
		{
			if (GetManagerFlags() & MANAGER_FLAG_BUFFER_DIRTY)
			{
				UpdateScrollBuffer();
			}

			// instead of invoking the Draw method of mRoot, just copy the contents of the
			//  buffer at this location.
			gc->CopyBufferRegion (
					&screenDirty,
					mScrollBuffer,
					screenDirty.left - screenView.left + (mViewRect.left % mViewRect.Width()),
					screenDirty.top  - screenView.top  + (mViewRect.top  % mViewRect.Height()));
		}
		else
		{

	  #endif

			gc->SetClip(&screenDirty);

			if (mRoot.Get())
			{
				mRoot.Get()->Draw(screenView.left + mRoot.Get()->mRect.left - scrollLeft,
				                  screenView.top  + mRoot.Get()->mRect.top  - scrollTop,
								  &screenView, gc);
			}

	  #ifdef WEBC_BUFFER_SCROLLING
		}
	  #endif

		gc->SetClip(&saveClip);
	}

	// draw the little gray rectangle
	if (mpVScroll && mpHScroll && webc_GetDefaultBoolean(WEBC_DEFAULT_DRAW_SCROLL_CORNER))
	{
		WebRect box;
		WebColor c = gc->RGBToColor(webc_GetDefaultColor(WEBC_DEFAULT_SCROLL_CORNER_COLOR));
		box.SetSizeAndPosition(screenView.right + 1, screenView.bottom + 1, mpVScroll->Width(), mpHScroll->Height());
		gc->Rectangle(&box, c, c, 1);
	}
}