예제 #1
0
void Window::DrawBackground(const Region* rgn) const
{
	Video* video = core->GetVideoDriver();
	if (rgn) {
		Region toClip = *rgn;
		toClip.x += XPos;
		toClip.y += YPos;
		video->BlitSprite( BackGround, *rgn, toClip);
	} else {
		video->BlitSprite( BackGround, XPos, YPos, true );
	}
}
예제 #2
0
/** This function Draws the Window on the Output Screen */
void Window::DrawWindow()
{
	if (!Visible) return; // no point in drawing invisible windows
	Video* video = core->GetVideoDriver();
	Region clip( XPos, YPos, Width, Height );
	//Frame && Changed
	if ( (Flags & (WF_FRAME|WF_CHANGED) ) == (WF_FRAME|WF_CHANGED) ) {
		Region screen( 0, 0, core->Width, core->Height );
		video->SetScreenClip( NULL );
		//removed this?
		video->DrawRect( screen, ColorBlack );
		if (core->WindowFrames[0])
			video->BlitSprite( core->WindowFrames[0], 0, 0, true );
		if (core->WindowFrames[1])
			video->BlitSprite( core->WindowFrames[1], core->Width - core->WindowFrames[1]->Width, 0, true );
		if (core->WindowFrames[2])
			video->BlitSprite( core->WindowFrames[2], (core->Width - core->WindowFrames[2]->Width) / 2, 0, true );
		if (core->WindowFrames[3])
			video->BlitSprite( core->WindowFrames[3], (core->Width - core->WindowFrames[3]->Width) / 2, core->Height - core->WindowFrames[3]->Height, true );
	}

	video->SetScreenClip( &clip );
	//Float || Changed
	bool bgRefreshed = false;
	if (BackGround && (Flags & (WF_FLOAT|WF_CHANGED) ) ) {
		DrawBackground(NULL);
		bgRefreshed = true;
	}

	std::vector< Control*>::iterator m;
	for (m = Controls.begin(); m != Controls.end(); ++m) {
		Control* c = *m;
		// FIXME: drawing BG in the same loop as controls can produce incorrect results with overlapping controls. the only case I know of this occuring it is ok due to no BG drawing
		// furthermore, overlapping controls are still a problem when NeedsDraw() returns false for the top control, but true for the bottom (see the level up icon on char portraits)
		// we will fix both issues later by refactoring with the concept of views and subviews
		if (BackGround && !bgRefreshed && !c->IsOpaque() && c->NeedsDraw()) {
			const Region& fromClip = c->ControlFrame();
			DrawBackground(&fromClip);
		}
		if (Flags & (WF_FLOAT)) {
			// FIXME: this is a total hack. Required for anything drawing over GameControl (nothing really at all to do with floating)
			c->MarkDirty();
		}
		c->Draw( XPos, YPos );
	}
	if ( (Flags&WF_CHANGED) && (Visible == WINDOW_GRAYED) ) {
		Color black = { 0, 0, 0, 128 };
		video->DrawRect(clip, black);
	}
	video->SetScreenClip( NULL );
	Flags &= ~WF_CHANGED;
}
예제 #3
0
/** Draws the Control on the Output Display */
void TextEdit::DrawInternal(Region& rgn)
{
	ieWord yOff = FontPosY;
	ieWord xOff = FontPosX;

	Video* video = core->GetVideoDriver();
	if (Back) {
		// FIXME: temporary hack for PST map labels.
		// once subviews branch is merged this is not needed
		video->DrawRect(rgn, ColorBlack);
		video->BlitSprite( Back, rgn.x, rgn.y, true );
		xOff += Back->XPos;
		yOff += Back->YPos;
	} else if (Text != L"") {
		// FIXME: temporary hack for PST map labels.
		// once subviews branch is merged this is not needed
		video->DrawRect(rgn, ColorBlack);
	}
	if (!font) {
		// no font was specified; happens with cheat input edits
		return;
	}

	//The aligning of textedit fields is done by absolute positioning (FontPosX, FontPosY)
	font->Print( Region( rgn.x + xOff, rgn.y + yOff, Width, Height ),
				 Text, palette, Alignment );

	if (hasFocus) {
		int w = font->StringSize(Text.substr(0, CurPos)).w;
		ieWord vcenter = (rgn.h / 2) + (Cursor->Height / 2);
		if (w > rgn.w) {
			int rows = (w / rgn.w);
			vcenter += rows * font->LineHeight;
			w = w - (rgn.w * rows);
		}
		video->BlitSprite(Cursor, w + rgn.x + xOff,
						  yOff + vcenter + rgn.y, true);
	}
}
예제 #4
0
/** This function Draws the Window on the Output Screen */
void Window::DrawWindow()
{
	Video* video = core->GetVideoDriver();
	Region clip( XPos, YPos, Width, Height );
	//Frame && Changed
	if ( (Flags & (WF_FRAME|WF_CHANGED) )== (WF_FRAME|WF_CHANGED) ) {
		Region screen( 0, 0, core->Width, core->Height );
		video->SetClipRect( NULL );
		//removed this?
		Color black = { 0, 0, 0, 255 };
		video->DrawRect( screen, black );
		if (core->WindowFrames[0])
			video->BlitSprite( core->WindowFrames[0], 0, 0, true );
		if (core->WindowFrames[1])
			video->BlitSprite( core->WindowFrames[1], core->Width - core->WindowFrames[1]->Width, 0, true );
		if (core->WindowFrames[2])
			video->BlitSprite( core->WindowFrames[2], (core->Width - core->WindowFrames[2]->Width) / 2, 0, true );
		if (core->WindowFrames[3])
			video->BlitSprite( core->WindowFrames[3], (core->Width - core->WindowFrames[3]->Width) / 2, core->Height - core->WindowFrames[3]->Height, true );
	} else if (clip_regions.size()) {
		// clip drawing (we only do Background right now) for InvalidateForControl
		for (unsigned int i = 0; i < clip_regions.size(); i++) {
			Region to_clip = clip_regions[i];
			to_clip.x += XPos;
			to_clip.y += YPos;
			video->SetClipRect(&to_clip);
			if (BackGround) {
				video->BlitSprite( BackGround, XPos, YPos, true );
			}
		}
	}
	clip_regions.clear();
	video->SetClipRect( &clip );
	//Float || Changed
	if (BackGround && (Flags & (WF_FLOAT|WF_CHANGED) ) ) {
		video->BlitSprite( BackGround, XPos, YPos, true );
	}
	std::vector< Control*>::iterator m;
	for (m = Controls.begin(); m != Controls.end(); ++m) {
		( *m )->Draw( XPos, YPos );
	}
	if ( (Flags&WF_CHANGED) && (Visible == WINDOW_GRAYED) ) {
		Color black = { 0, 0, 0, 128 };
		video->DrawRect(clip, black);
	}
	video->SetClipRect( NULL );
	Flags &= ~WF_CHANGED;
}
예제 #5
0
파일: Button.cpp 프로젝트: BehoIder/gemrb
/** Draws the Control on the Output Display */
void Button::DrawInternal(Region& rgn)
{
	Video * video = core->GetVideoDriver();

	// Button image
	if (!( Flags & IE_GUI_BUTTON_NO_IMAGE )) {
		Sprite2D* Image = NULL;

		switch (State) {
			case IE_GUI_BUTTON_UNPRESSED:
			case IE_GUI_BUTTON_LOCKED:
			case IE_GUI_BUTTON_LOCKED_PRESSED:
				Image = buttonImages[BUTTON_IMAGE_UNPRESSED];
				break;
			case IE_GUI_BUTTON_FAKEPRESSED:
			case IE_GUI_BUTTON_PRESSED:
				Image = buttonImages[BUTTON_IMAGE_PRESSED];
				break;
			case IE_GUI_BUTTON_SELECTED:
				Image = buttonImages[BUTTON_IMAGE_SELECTED];
				break;
			case IE_GUI_BUTTON_DISABLED:
			case IE_GUI_BUTTON_FAKEDISABLED:
				Image = buttonImages[BUTTON_IMAGE_DISABLED];
				break;
		}
		if (!Image) {
			Image = buttonImages[BUTTON_IMAGE_UNPRESSED];
		}
		if (Image) {
			// FIXME: maybe it's useless...
			int xOffs = ( Width / 2 ) - ( Image->Width / 2 );
			int yOffs = ( Height / 2 ) - ( Image->Height / 2 );

			video->BlitSprite( Image, rgn.x + xOffs, rgn.y + yOffs, true );
		}
	}

	if (State == IE_GUI_BUTTON_PRESSED) {
		//shift the writing/border a bit
		rgn.x += PushOffset.x;
		rgn.y += PushOffset.y;
	}

	// Button picture
	if (AnimPicture) {
		int xOffs = ( Width / 2 ) - ( AnimPicture->Width / 2 );
		int yOffs = ( Height / 2 ) - ( AnimPicture->Height / 2 );
		Region r( rgn.x + xOffs, rgn.y + yOffs, (int)(AnimPicture->Width * Clipping), AnimPicture->Height );

		if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) {
			video->BlitSprite( AnimPicture, rgn.x + xOffs + AnimPicture->XPos, rgn.y + yOffs + AnimPicture->YPos, true, &r );
		} else {
			video->BlitSprite( AnimPicture, rgn.x + xOffs, rgn.y + yOffs, true, &r );
		}
	}

	// Button picture
	int picXPos = 0, picYPos = 0;
	if (Picture && (Flags & IE_GUI_BUTTON_PICTURE) ) {
		// Picture is drawn centered
		picXPos = ( rgn.w / 2 ) - ( Picture->Width / 2 ) + rgn.x;
		picYPos = ( rgn.h / 2 ) - ( Picture->Height / 2 ) + rgn.y;
		if (Flags & IE_GUI_BUTTON_HORIZONTAL) {
			picXPos += Picture->XPos;
			picYPos += Picture->YPos;

			// Clipping: 0 = overlay over full button, 1 = no overlay
			int overlayHeight = Picture->Height * (1.0 - Clipping);
			if (overlayHeight < 0)
				overlayHeight = 0;
			if (overlayHeight >= Picture->Height)
				overlayHeight = Picture->Height;
			int buttonHeight = Picture->Height - overlayHeight;

			Region rb = Region(picXPos, picYPos, Picture->Width, buttonHeight);
			Region ro = Region(picXPos, picYPos + buttonHeight, Picture->Width, overlayHeight);

			video->BlitSprite( Picture, picXPos, picYPos, true, &rb );

			// TODO: Add an option to add BLIT_GREY to the flags
			video->BlitGameSprite( Picture, picXPos, picYPos, BLIT_TINTED, SourceRGB, 0, 0, &ro, true);

			// do NOT uncomment this, you can't change Changed or invalidate things from
			// the middle of Window::DrawWindow() -- it needs moving to somewhere else
			//CloseUpColor();
		}
		else {
			Region r( picXPos, picYPos, (int)(Picture->Width * Clipping), Picture->Height );
			video->BlitSprite( Picture, picXPos + Picture->XPos, picYPos + Picture->YPos, true, &r );
		}
	}

	// Composite pictures (paperdolls/description icons)
	if (!PictureList.empty() && (Flags & IE_GUI_BUTTON_PICTURE) ) {
		std::list<Sprite2D*>::iterator iter = PictureList.begin();
		int xOffs = 0, yOffs = 0;
		if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) {
			// Center the hotspots of all pictures
			xOffs = Width/2;
			yOffs = Height/2;
		} else if (Flags & IE_GUI_BUTTON_BG1_PAPERDOLL) {
			// Display as-is
			xOffs = 0;
			yOffs = 0;
		} else {
			// Center the first picture, and align the rest to that
			xOffs = Width/2 - (*iter)->Width/2 + (*iter)->XPos;
			yOffs = Height/2 - (*iter)->Height/2 + (*iter)->YPos;
		}

		for (; iter != PictureList.end(); ++iter) {
			video->BlitSprite( *iter, rgn.x + xOffs, rgn.y + yOffs, true );
		}
	}

	// Button label
	if (hasText && ! ( Flags & IE_GUI_BUTTON_NO_TEXT )) {
		Palette* ppoi = normal_palette;
		int align = 0;

		if (State == IE_GUI_BUTTON_DISABLED)
			ppoi = disabled_palette;
		// FIXME: hopefully there's no button which sinks when selected
		//   AND has text label
		//else if (State == IE_GUI_BUTTON_PRESSED || State == IE_GUI_BUTTON_SELECTED) {

		if (Flags & IE_GUI_BUTTON_ALIGN_LEFT)
			align |= IE_FONT_ALIGN_LEFT;
		else if (Flags & IE_GUI_BUTTON_ALIGN_RIGHT)
			align |= IE_FONT_ALIGN_RIGHT;
		else
			align |= IE_FONT_ALIGN_CENTER;

		if (Flags & IE_GUI_BUTTON_ALIGN_TOP)
			align |= IE_FONT_ALIGN_TOP;
		else if (Flags & IE_GUI_BUTTON_ALIGN_BOTTOM)
			align |= IE_FONT_ALIGN_BOTTOM;
		else
			align |= IE_FONT_ALIGN_MIDDLE;

		if (! (Flags & IE_GUI_BUTTON_MULTILINE)) {
			align |= IE_FONT_SINGLE_LINE;
		}

		Region r;
		if (Picture && (Flags & IE_GUI_BUTTON_PORTRAIT) == IE_GUI_BUTTON_PORTRAIT) {
			// constrain the label (status icons) to the picture bounds
			// FIXME: we are subtracting IE_FONT_PADDING because Font indents 5px, but we dont want that here
			r = Region(picXPos - IE_FONT_PADDING, picYPos + IE_FONT_PADDING,
					   Picture->Width + IE_FONT_PADDING, Picture->Height);
		} else {
			r = Region( rgn.x, rgn.y, rgn.w - 2, rgn.h - 2);
		}

		font->Print( r, ( unsigned char * ) Text, ppoi, (ieByte) align, true );
	}

	if (! (Flags&IE_GUI_BUTTON_NO_IMAGE)) {
		for (int i = 0; i < MAX_NUM_BORDERS; i++) {
			ButtonBorder *fr = &borders[i];
			if (! fr->enabled) continue;

			Region r = Region( rgn.x + fr->dx1, rgn.y + fr->dy1, rgn.w - (fr->dx1 + fr->dx2 + 1), rgn.h - (fr->dy1 + fr->dy2 + 1) );
			video->DrawRect( r, fr->color, fr->filled );
		}
	}
}
예제 #6
0
/** Draws the Control on the Output Display */
void MapControl::Draw(unsigned short XWin, unsigned short YWin)
{
	if (!Width || !Height) {
		return;
	}
	if (Owner->Visible!=WINDOW_VISIBLE) {
		return;
	}

	if (Changed) {
		Realize();
		Changed = false;
	}

	// we're going to paint over labels/etc, so they need to repaint!
	bool seen_this = false;
	unsigned int i;
	for (i = 0; i < Owner->GetControlCount(); i++) {
		Control *ctrl = Owner->GetControl(i);
		if (!ctrl) continue;

		// we could try working out which controls overlap,
		// but the later controls are cheap to paint..
		if (ctrl == this) { seen_this = true; continue; }
		if (!seen_this) continue;

		ctrl->Changed = true;
	}

	Video* video = core->GetVideoDriver();
	Region r( XWin + XPos, YWin + YPos, Width, Height );

	if (MapMOS) {
		video->BlitSprite( MapMOS, MAP_TO_SCREENX(0), MAP_TO_SCREENY(0), true, &r );
	}

	if (core->FogOfWar&FOG_DRAWFOG)
		DrawFog(XWin, YWin);

	Region vp = video->GetViewport();

	vp.x = GAME_TO_SCREENX(vp.x);
	vp.y = GAME_TO_SCREENY(vp.y);
	vp.w = ViewWidth;
	vp.h = ViewHeight;

	if ((vp.x + vp.w) >= MAP_TO_SCREENX( Width ))
		vp.w = MAP_TO_SCREENX( Width ) - vp.x;
	if ((vp.y + vp.h) >= MAP_TO_SCREENY( Height ))
		vp.h = MAP_TO_SCREENY( Height ) - vp.y;

	video->DrawRect( vp, colors[green], false, false );

	// Draw PCs' ellipses
	Game *game = core->GetGame();
	i = game->GetPartySize(true);
	while (i--) {
		Actor* actor = game->GetPC( i, true );
		if (MyMap->HasActor(actor) ) {
			video->DrawEllipse( (short) GAME_TO_SCREENX(actor->Pos.x), (short) GAME_TO_SCREENY(actor->Pos.y), 3, 2, actor->Selected ? colors[green] : colors[darkgreen], false );
		}
	}
	// Draw Map notes, could be turned off in bg2
	// we use the common control value to handle it, because then we
	// don't need another interface
	if (Value!=MAP_NO_NOTES) {
		i = MyMap -> GetMapNoteCount();
		while (i--) {
			MapNote * mn = MyMap -> GetMapNote(i);
			Sprite2D *anim = Flag[mn->color&7];
			Point pos = mn->Pos;
			if (convertToGame) {
				vp.x = GAME_TO_SCREENX(mn->Pos.x);
				vp.y = GAME_TO_SCREENY(mn->Pos.y);
			} else { //pst style
				vp.x = MAP_TO_SCREENX(mn->Pos.x);
				vp.y = MAP_TO_SCREENY(mn->Pos.y);
				pos.x = pos.x * MAP_MULT / MAP_DIV;
				pos.y = pos.y * MAP_MULT / MAP_DIV;
			}

			//Skip unexplored map notes
			bool visible = MyMap->IsVisible( pos, true );
			if (!visible)
				continue;

			if (anim) {
				video->BlitSprite( anim, vp.x - anim->Width/2, vp.y - anim->Height/2, true, &r );
			} else {
				video->DrawEllipse( (short) vp.x, (short) vp.y, 6, 5, colors[mn->color&7], false );
			}
		}
	}
}
예제 #7
0
/** Draws the Control on the Output Display */
void Button::Draw(unsigned short x, unsigned short y)
{
	if (!Changed && !(Owner->Flags&WF_FLOAT) ) {
		return;
	}
	Changed = false;
	if (XPos == 65535 || Width == 0) {
		return;
	}

	Video * video = core->GetVideoDriver();

	// Button image
	if (!( Flags & IE_GUI_BUTTON_NO_IMAGE )) {
		Sprite2D* Image = NULL;

		switch (State) {
			case IE_GUI_BUTTON_UNPRESSED:
			case IE_GUI_BUTTON_LOCKED:
			case IE_GUI_BUTTON_LOCKED_PRESSED:
				Image = Unpressed;
				break;

			case IE_GUI_BUTTON_SECOND:
			case IE_GUI_BUTTON_PRESSED:
				Image = Pressed;
				if (! Image)
					Image = Unpressed;
				break;

			case IE_GUI_BUTTON_SELECTED:
				Image = Selected;
				if (! Image)
					Image = Unpressed;
				break;

			case IE_GUI_BUTTON_DISABLED:
			case IE_GUI_BUTTON_THIRD:
				Image = Disabled;
				if (! Image)
					Image = Unpressed;
				break;
		}
		if (Image) {
			// FIXME: maybe it's useless...
			int xOffs = ( Width / 2 ) - ( Image->Width / 2 );
			int yOffs = ( Height / 2 ) - ( Image->Height / 2 );

			video->BlitSprite( Image, x + XPos + xOffs, y + YPos + yOffs, true );
		}
	}

	if (State == IE_GUI_BUTTON_PRESSED) {
		//shift the writing/border a bit
		x+= 2;
		y+= 2;
	}

	// Button picture
	if (Picture  && (Flags & IE_GUI_BUTTON_PICTURE) ) {
		// Picture is drawn centered
		int xOffs = ( Width / 2 ) - ( Picture->Width / 2 );
		int yOffs = ( Height / 2 ) - ( Picture->Height / 2 );
		if (Flags & IE_GUI_BUTTON_HORIZONTAL) {
			xOffs += x + XPos + Picture->XPos;
			yOffs += y + YPos + Picture->YPos;
			video->BlitSprite( Picture, xOffs, yOffs, true );
			Region r = Region( xOffs, yOffs + (int) (Picture->Height * Clipping), Picture->Width, (int) (Picture->Height*(1.0 - Clipping)) );
			video->DrawRect( r, SourceRGB, true );
			// do NOT uncomment this, you can't change Changed or invalidate things from
			// the middle of Window::DrawWindow() -- it needs moving to somewhere else
			//CloseUpColor();
		}
		else {
			Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(Picture->Width * Clipping), Picture->Height );
			video->BlitSprite( Picture, x + XPos + xOffs + Picture->XPos, y + YPos + yOffs + Picture->YPos, true, &r );
		}
	}

	// Composite pictures (paperdolls/description icons)
	if (!PictureList.empty() && (Flags & IE_GUI_BUTTON_PICTURE) ) {
		std::list<Sprite2D*>::iterator iter = PictureList.begin();
		int xOffs = 0, yOffs = 0;
		if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) {
			// Center the hotspots of all pictures
			xOffs = Width/2;
			yOffs = Height/2;
		} else if (Flags & IE_GUI_BUTTON_BG1_PAPERDOLL) {
			// Display as-is
			xOffs = 0;
			yOffs = 0;
		} else {
			// Center the first picture, and align the rest to that
			xOffs = Width/2 - (*iter)->Width/2 + (*iter)->XPos;
			yOffs = Height/2 - (*iter)->Height/2 + (*iter)->YPos;
		}

		for (; iter != PictureList.end(); ++iter) {
			video->BlitSprite( *iter, x + XPos + xOffs, y + YPos + yOffs, true );
		}
	}

	// Button picture
	if (AnimPicture) {
		int xOffs = ( Width / 2 ) - ( AnimPicture->Width / 2 );
		int yOffs = ( Height / 2 ) - ( AnimPicture->Height / 2 );
		Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(AnimPicture->Width * Clipping), AnimPicture->Height );

		if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) {
			video->BlitSprite( AnimPicture, x + XPos + xOffs + AnimPicture->XPos, y + YPos + yOffs + AnimPicture->YPos, true, &r );
		} else {
			video->BlitSprite( AnimPicture, x + XPos + xOffs, y + YPos + yOffs, true, &r );
		}
	}

	// Button label
	if (hasText && ! ( Flags & IE_GUI_BUTTON_NO_TEXT )) {
		Palette* ppoi = normal_palette;
		int align = 0;

		if (State == IE_GUI_BUTTON_DISABLED)
			ppoi = disabled_palette;
		// FIXME: hopefully there's no button which sinks when selected
		//   AND has text label
		//else if (State == IE_GUI_BUTTON_PRESSED || State == IE_GUI_BUTTON_SELECTED) {

		if (Flags & IE_GUI_BUTTON_ALIGN_LEFT)
			align |= IE_FONT_ALIGN_LEFT;
		else if (Flags & IE_GUI_BUTTON_ALIGN_RIGHT)
			align |= IE_FONT_ALIGN_RIGHT;
		else
			align |= IE_FONT_ALIGN_CENTER;

		if (Flags & IE_GUI_BUTTON_ALIGN_TOP)
			align |= IE_FONT_ALIGN_TOP;
		else if (Flags & IE_GUI_BUTTON_ALIGN_BOTTOM)
			align |= IE_FONT_ALIGN_BOTTOM;
		else
			align |= IE_FONT_ALIGN_MIDDLE;

		if (! (Flags & IE_GUI_BUTTON_MULTILINE)) {
			align |= IE_FONT_SINGLE_LINE;
		}
		font->Print( Region( x + XPos, y + YPos, Width - 2, Height - 2),
			( unsigned char * ) Text, ppoi,
			(ieByte) align, true );
	}

	if (! (Flags&IE_GUI_BUTTON_NO_IMAGE)) {
		for (int i = 0; i < MAX_NUM_BORDERS; i++) {
			ButtonBorder *fr = &borders[i];
			if (! fr->enabled) continue;

			Region r = Region( x + XPos + fr->dx1, y + YPos + fr->dy1, Width - (fr->dx1 + fr->dx2 + 1), Height - (fr->dy1 + fr->dy2 + 1) );
			video->DrawRect( r, fr->color, fr->filled );
		}
	}
}
예제 #8
0
파일: Font.cpp 프로젝트: JeremyAgost/gemrb
void Font::Print(Region cliprgn, Region rgn, const unsigned char* string,
                 Palette* hicolor, unsigned char Alignment, bool anchor, Font* initials,
                 Sprite2D* cursor, unsigned int curpos, bool NoColor) const
{
    bool enablecap=false;
    int capital = 0;
    if (initials)
    {
        capital=1;
        enablecap=true;
    }
    (void)enablecap; //HACK: shut up unused-but-set warnings, until the var is reused

    unsigned int psx = PARAGRAPH_START_X;
    Palette* pal = hicolor;
    if (!pal) {
        pal = palette;
    }
    if (initials==this) {
        initials = NULL;
    }

    sprBuffer->SetPalette( pal );
    size_t len = strlen( ( char* ) string );
    char* tmp = ( char* ) malloc( len + 1 );
    memcpy( tmp, ( char * ) string, len + 1 );
    while (len > 0 && (tmp[len - 1] == '\n' || tmp[len - 1] == '\r')) {
        // ignore trailing newlines
        tmp[len - 1] = 0;
        len--;
    }

    SetupString( tmp, rgn.w, NoColor, initials, capital );
    int ystep = 0;
    if (Alignment & IE_FONT_SINGLE_LINE) {

        for (size_t i = 0; i < len; i++) {
            if (tmp[i] == 0) continue;
            int height = yPos[( unsigned char ) tmp[i] - 1];
            if (ystep < height)
                ystep = height;
        }
    } else {
        ystep = size[1].h;
    }
    if (!ystep) ystep = maxHeight;
    int x = psx, y = ystep;
    Video* video = core->GetVideoDriver();

    if (Alignment & IE_FONT_ALIGN_CENTER) {
        int w = CalcStringWidth( tmp, NoColor );
        x = ( rgn.w - w ) / 2;
    } else if (Alignment & IE_FONT_ALIGN_RIGHT) {
        int w = CalcStringWidth( tmp, NoColor );
        x = ( rgn.w - w );
    }

    if (Alignment & IE_FONT_ALIGN_MIDDLE) {
        int h = 0;
        for (size_t i = 0; i <= len; i++) {
            if (tmp[i] == 0)
                h++;
        }
        h = h * ystep;
        y += ( rgn.h - h ) / 2;
    } else if (Alignment & IE_FONT_ALIGN_BOTTOM) {
        int h = 1;
        for (size_t i = 0; i <= len; i++) {
            if (tmp[i] == 0)
                h++;
        }
        h = h * ystep;
        y += ( rgn.h - h );
    } else if (Alignment & IE_FONT_ALIGN_TOP) {
        y += 5;
    }
    for (size_t i = 0; i < len; i++) {
        if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) {
            i++;
            char tag[256];
            tag[0]=0;
            for (int k = 0; k < 256 && i<len; k++) {
                if (tmp[i] == ']') {
                    tag[k] = 0;
                    break;
                }
                tag[k] = tmp[i++];
            }

            if (strnicmp( tag, "capital=",8)==0) {
                sscanf( tag, "capital=%d", &capital);
                if (capital) {
                    enablecap=true;
                }
                continue;
            }

            if (strnicmp( tag, "color=", 6 ) == 0) {
                unsigned int r,g,b;
                if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3)
                    continue;
                const Color c = {(unsigned char) r,(unsigned char) g,(unsigned char)  b, 0};
                Palette* newPal = core->CreatePalette( c, palette->back );
                sprBuffer->SetPalette( newPal );
                gamedata->FreePalette( newPal );
                continue;
            }
            if (stricmp( tag, "/color" ) == 0) {
                sprBuffer->SetPalette( pal );
                continue;
            }
            if (stricmp( "p", tag ) == 0) {
                psx = x;
                continue;
            }
            if (stricmp( "/p", tag ) == 0) {
                psx = PARAGRAPH_START_X;
                continue;
            }
            continue;
        }

        if (tmp[i] == 0) {
            y += ystep;
            x = psx;
            int w = CalcStringWidth( &tmp[i + 1], NoColor );
            if (Alignment & IE_FONT_ALIGN_CENTER) {
                x = ( rgn.w - w ) / 2;
            } else if (Alignment & IE_FONT_ALIGN_RIGHT) {
                x = ( rgn.w - w );
            }
            continue;
        }
        unsigned char currChar = ( unsigned char ) tmp[i] - 1;
        if (initials && capital) {
            x = initials->PrintInitial( x, y, rgn, currChar );
            enablecap=false;
            continue;
        }
        video->BlitSpriteRegion( sprBuffer, size[currChar],
                                 x + rgn.x, y + rgn.y - yPos[currChar],
                                 anchor, &cliprgn );
        if (cursor && ( curpos == i ))
            video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn );
        x += size[currChar].w;
    }
    if (cursor && ( curpos == len )) {
        video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn );
    }
    free( tmp );
}
예제 #9
0
파일: Font.cpp 프로젝트: JeremyAgost/gemrb
void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string,
                         Palette* hicolor, unsigned char Alignment, Font* initials,
                         Sprite2D* cursor, unsigned int curpos, bool NoColor) const
{
    bool enablecap=false;
    int capital = 0;
    int initials_rows = 0;
    int last_initial_row = 0;
    int initials_x = 0;
    int initials_row = 0;
    unsigned char currCap = 0;
    size_t len = strlen( ( char* ) string );
    int num_empty_rows = 0;

    if (initials)
    {
        capital=1;
        enablecap=true;
        initials_rows = ((initials->maxHeight - 1) / maxHeight) - (startrow - 1);

        currCap = string[0] - 1;
        if ((startrow > 0 && initials_rows > 0) || (len > 0 && isspace(currCap))) { // we need to look back to get the cap
            while(isspace(currCap) && num_empty_rows < (int)len) { //we cant cap whitespace so keep looking
                currCap = string[++num_empty_rows] - 1;
                // WARNING: this assumes all preceeding whitespace is an empty line
            }
            last_initial_row = (startrow - 1);
            initials_rows--;
        }
    }

    unsigned int psx = PARAGRAPH_START_X;
    Palette *pal = hicolor;
    if (!pal) {
        pal = palette;
    }

    if (initials==this) {
        enablecap=false;
    }

    sprBuffer->SetPalette( pal );

    char* tmp = ( char* ) malloc( len + 1 );
    memcpy( tmp, ( char * ) string, len + 1 );
    SetupString( tmp, rgn.w, NoColor, initials, enablecap );

    if (startrow) enablecap=false;
    int ystep = 0;
    if (Alignment & IE_FONT_SINGLE_LINE) {
        for (size_t i = 0; i < len; i++) {
            int height = yPos[( unsigned char ) tmp[i] - 1];
            if (ystep < height)
                ystep = height;
        }
    } else {
        ystep = size[1].h;
    }
    if (!ystep) ystep = maxHeight;
    int x = psx, y = ystep;
    int w = CalcStringWidth( tmp, NoColor );
    if (Alignment & IE_FONT_ALIGN_CENTER) {
        x = ( rgn.w - w) / 2;
    } else if (Alignment & IE_FONT_ALIGN_RIGHT) {
        x = ( rgn.w - w );
    }
    if (Alignment & IE_FONT_ALIGN_MIDDLE) {
        int h = 0;
        for (size_t i = 0; i <= len; i++) {
            if (( tmp[i] == 0 ) || ( tmp[i] == '\n' ))
                h++;
        }
        h = h * ystep;
        y += ( rgn.h - h ) / 2;
    } else if (Alignment & IE_FONT_ALIGN_BOTTOM) {
        int h = 1;
        for (size_t i = 0; i <= len; i++) {
            if (( tmp[i] == 0 ) || ( tmp[i] == '\n' ))
                h++;
        }
        h = h * ystep;
        y += ( rgn.h - h );
    } else if (Alignment & IE_FONT_ALIGN_TOP) {
        y += 5;
    }

    Video* video = core->GetVideoDriver();
    int row = 0;
    for (size_t i = 0; i < len; i++) {
        if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) {
            i++;
            char tag[256];
            tag[0]=0;

            for (int k = 0; k < 256 && i<len; k++) {
                if (tmp[i] == ']') {
                    tag[k] = 0;
                    break;
                }
                tag[k] = tmp[i++];
            }

            if (strnicmp( tag, "capital=",8)==0) {
                sscanf( tag, "capital=%d", &capital);
                if (capital && (row>=startrow) ) {
                    enablecap=true;
                }
                continue;
            }

            if (strnicmp( tag, "color=", 6 ) == 0) {
                unsigned int r,g,b;
                if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3)
                    continue;
                const Color c = {(unsigned char) r,(unsigned char)g, (unsigned char)b, 0};
                Palette* newPal = core->CreatePalette( c, palette->back );
                sprBuffer->SetPalette( newPal );
                gamedata->FreePalette( newPal );
                continue;
            }
            if (stricmp( tag, "/color" ) == 0) {
                sprBuffer->SetPalette( pal );
                continue;
            }
            if (stricmp( "p", tag ) == 0) {
                psx = x;
                continue;
            }
            if (stricmp( "/p", tag ) == 0) {
                psx = PARAGRAPH_START_X;
            }
            continue;
        }

        if (row < startrow) {
            if (tmp[i] == 0) {
                row++;
            }
            continue;
        }
        if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) {
            y += ystep;
            x = psx;
            int w = CalcStringWidth( &tmp[i + 1], NoColor );
            if (initials_rows > 0) {
                initials_rows--;
                x += initials_x;
                w += initials_x;
            }
            if (Alignment & IE_FONT_ALIGN_CENTER) {
                x = ( rgn.w - w ) / 2;
            } else if (Alignment & IE_FONT_ALIGN_RIGHT) {
                x = ( rgn.w - w );
            }
            continue;
        }
        unsigned char currChar = ( unsigned char ) tmp[i] - 1;
        if (initials && capital && enablecap) {
            currCap = currChar;
            x = initials->PrintInitial( x, y, rgn, currChar );
            initials_x = x;

            //how many more lines to be indented (one was already indented)
            initials_rows = (initials->maxHeight-1)/maxHeight;
            initials_row = row;
            last_initial_row = initials_row;

            enablecap = false;
            continue;
        } else if(initials && currCap && row > last_initial_row && (row - num_empty_rows - initials_row) <= ((initials->maxHeight-1)/maxHeight)) {
            // means this row doesnt have a cap, but a preceeding one did and its overlapping this row
            int initY = y;
            if (!num_empty_rows) {// num_empty_rows is for scrolling text areas
                initY = (y - (maxHeight * (row - initials_row)));
            }
            x = initials->PrintInitial( x, initY, rgn, currCap );
            initials_x = x;
            x += psx;
            last_initial_row++;
        }
        video->BlitSpriteRegion( sprBuffer, size[currChar],
                                 x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn );
        if (cursor && ( i == curpos )) {
            video->BlitSprite( cursor, x + rgn.x,
                               y + rgn.y, true, &rgn );
        }
        x += size[currChar].w;
    }
    if (cursor && ( curpos == len )) {
        video->BlitSprite( cursor, x + rgn.x,
                           y + rgn.y, true, &rgn );
    }
    free( tmp );
}
예제 #10
0
void TextArea::Draw(unsigned short x, unsigned short y)
{
	/** Don't come back recursively */
	if (InternalFlags&TA_BITEMYTAIL) {
		return;
	}
	int tx=x+XPos;
	int ty=y+YPos;
	Region clip( tx, ty, Width, Height );
	Video *video = core->GetVideoDriver();

	if (Flags&IE_GUI_TEXTAREA_SPEAKER) {
		if (AnimPicture) {
			video->BlitSprite(AnimPicture, tx,ty, true, &clip);
			clip.x+=AnimPicture->Width;
			clip.w-=AnimPicture->Width;
		}
	}

	//this might look better in GlobalTimer
	//or you might want to change the animated button to work like this
	if (Flags &IE_GUI_TEXTAREA_SMOOTHSCROLL)
	{
		unsigned long thisTime;

		GetTime( thisTime);
		if (thisTime>starttime) {
			starttime = thisTime+ticks;
			smooth--;
			while (smooth<=0) {
				smooth+=ftext->maxHeight;
				if (startrow<rows) {
					startrow++;
				}
			}

			/** Forcing redraw of whole screen before drawing text*/
			Owner->Invalidate();
			InternalFlags |= TA_BITEMYTAIL;
			Owner->DrawWindow();
			InternalFlags &= ~TA_BITEMYTAIL;
		}
	}

	if (!Changed && !(Owner->Flags&WF_FLOAT) ) {
		return;
	}
	Changed = false;

	if (XPos == 65535) {
		return;
	}
	size_t linesize = lines.size();
	if (linesize == 0) {
		return;
	}

	//smooth vertical scrolling up
	if (Flags & IE_GUI_TEXTAREA_SMOOTHSCROLL) {
		clip.y+=smooth;
		clip.h-=smooth;
	}

	//if textarea is 'selectable' it actually means, it is a listbox
	//in this case the selected value equals the line number
	//if it is 'not selectable' it can still have selectable lines
	//but then it is like the dialog window in the main game screen:
	//the selected value is encoded into the line
	if (!(Flags & IE_GUI_TEXTAREA_SELECTABLE) ) {
		char* Buffer = (char *) malloc( 1 );
		Buffer[0] = 0;
		int len = 0;
		int lastlen = 0;
		for (size_t i = 0; i < linesize; i++) {
			if (strnicmp( "[s=", lines[i], 3 ) == 0) {
				int tlen;
				unsigned long idx, acolor, bcolor;
				char* rest;
				idx = strtoul( lines[i] + 3, &rest, 0 );
				if (*rest != ',')
					goto notmatched;
				acolor = strtoul( rest + 1, &rest, 16 );
				if (*rest != ',')
					goto notmatched;
				bcolor = strtoul( rest + 1, &rest, 16 );
				if (*rest != ']')
					goto notmatched;
				tlen = (int)(strstr( rest + 1, "[/s]" ) - rest - 1);
				if (tlen < 0)
					goto notmatched;
				len += tlen + 23;
				Buffer = (char *) realloc( Buffer, len + 2 );
				if (seltext == (int) i) {
					sprintf( Buffer + lastlen, "[color=%6.6lX]%.*s[/color]",
						acolor, tlen, rest + 1 );
				} else {
					sprintf( Buffer + lastlen, "[color=%6.6lX]%.*s[/color]",
						bcolor, tlen, rest + 1 );
				}
			} else {
				notmatched:
				len += ( int ) strlen( lines[i] ) + 1;
				Buffer = (char *) realloc( Buffer, len + 2 );
				memcpy( &Buffer[lastlen], lines[i], len - lastlen );
			}
			lastlen = len;
			if (i != linesize - 1) {
				Buffer[lastlen - 1] = '\n';
				Buffer[lastlen] = 0;
			}
		}
		video->SetClipRect( &clip );

		int pos;

		if (startrow==CurLine) {
			pos = CurPos;
		} else {
			pos = -1;
		}
		ftext->PrintFromLine( startrow, clip,
			( unsigned char * ) Buffer, palette,
			IE_FONT_ALIGN_LEFT, finit, Cursor, pos );
		free( Buffer );
		video->SetClipRect( NULL );
		//streaming text
		if (linesize>50) {
			//the buffer is filled enough
			return;
		}
		if (core->GetAudioDrv()->IsSpeaking() ) {
			//the narrator is still talking
			return;
		}
		if (RunEventHandler( TextAreaOutOfText )) {
			return;
		}
		if (linesize==lines.size()) {
			ResetEventHandler( TextAreaOutOfText );
			return;
		}
		AppendText("\n",-1);
		return;
	}
	// normal scrolling textarea
	int rc = 0;
	int sr = startrow;
	unsigned int i;
	int yl;
	for (i = 0; i < linesize; i++) {
		if (rc + lrows[i] <= sr) {
			rc += lrows[i];
			continue;
		}
		sr -= rc;
		Palette* pal = NULL;
		if (seltext == (int) i)
			pal = selected;
		else if (Value == i)
			pal = lineselpal;
		else
			pal = palette;
		ftext->PrintFromLine( sr, clip,
			( unsigned char * ) lines[i], pal,
			IE_FONT_ALIGN_LEFT, finit, NULL );
		yl = ftext->size[1].h*(lrows[i]-sr);
		clip.y+=yl;
		clip.h-=yl;
		break;
	}
	for (i++; i < linesize; i++) {
		Palette* pal = NULL;
		if (seltext == (int) i)
			pal = selected;
		else if (Value == i)
			pal = lineselpal;
		else
			pal = palette;
		ftext->Print( clip, ( unsigned char * ) lines[i], pal,
			IE_FONT_ALIGN_LEFT, true );
		yl = ftext->size[1].h*lrows[i];
		clip.y+=yl;
		clip.h-=yl;

	}
}
예제 #11
0
파일: Font.cpp 프로젝트: dhewg/gemrb
void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string,
	Palette* hicolor, unsigned char Alignment, Font* initials,
	Sprite2D* cursor, unsigned int curpos, bool NoColor) const
{
	bool enablecap=false;
	int capital = 0;
	if (initials)
	{
		capital=1;
		enablecap=true;
	}
	int initials_rows = 0;
	int initials_x = 0;

	unsigned int psx = PARAGRAPH_START_X;
	Palette *pal = hicolor;
	if (!pal) {
		pal = palette;
	}
	if (startrow) enablecap=false;

	if (initials==this) {
		enablecap=false;
	}

	sprBuffer->SetPalette( pal );
	size_t len = strlen( ( char* ) string );
	char* tmp = ( char* ) malloc( len + 1 );
	memcpy( tmp, ( char * ) string, len + 1 );
	SetupString( tmp, rgn.w, NoColor, initials, enablecap );
	int ystep = 0;
	if (Alignment & IE_FONT_SINGLE_LINE) {
		for (size_t i = 0; i < len; i++) {
			int height = yPos[( unsigned char ) tmp[i] - 1];
			if (ystep < height)
				ystep = height;
		}
	} else {
		ystep = size[1].h;
	}
	if (!ystep) ystep = maxHeight;
	int x = psx, y = ystep;
	int w = CalcStringWidth( tmp, NoColor );
	if (Alignment & IE_FONT_ALIGN_CENTER) {
		x = ( rgn.w - w) / 2;
	} else if (Alignment & IE_FONT_ALIGN_RIGHT) {
		x = ( rgn.w - w );
	}
	if (Alignment & IE_FONT_ALIGN_MIDDLE) {
		int h = 0;
		for (size_t i = 0; i <= len; i++) {
			if (( tmp[i] == 0 ) || ( tmp[i] == '\n' ))
				h++;
		}
		h = h * ystep;
		y += ( rgn.h - h ) / 2;
	} else if (Alignment & IE_FONT_ALIGN_BOTTOM) {
		int h = 1;
		for (size_t i = 0; i <= len; i++) {
			if (( tmp[i] == 0 ) || ( tmp[i] == '\n' ))
				h++;
		}
		h = h * ystep;
		y += ( rgn.h - h );
	} else if (Alignment & IE_FONT_ALIGN_TOP) {
		y += 5;
	}

	Video* video = core->GetVideoDriver();
	int row = 0;
	for (size_t i = 0; i < len; i++) {
		if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) {
			i++;
			char tag[256];
			tag[0]=0;

			for (int k = 0; k < 256 && i<len; k++) {
				if (tmp[i] == ']') {
					tag[k] = 0;
					break;
				}
				tag[k] = tmp[i++];
			}

			if (strnicmp( tag, "capital=",8)==0) {
				sscanf( tag, "capital=%d", &capital);
				if (capital && (row>=startrow) ) {
					enablecap=true;
				}
				continue;
			}

			
			if (strnicmp( tag, "color=", 6 ) == 0) {
				unsigned int r,g,b;
				if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3)
					continue;
				const Color c = {(unsigned char) r,(unsigned char)g, (unsigned char)b, 0};
				Palette* newPal = core->CreatePalette( c, palette->back );
				sprBuffer->SetPalette( newPal );
				gamedata->FreePalette( newPal );
				continue;
			}
			if (stricmp( tag, "/color" ) == 0) {
				sprBuffer->SetPalette( pal );
				continue;
			}
			
			if (stricmp( "p", tag ) == 0) {
				psx = x;
				continue;
			}
			if (stricmp( "/p", tag ) == 0) {
				psx = PARAGRAPH_START_X;
			}
			continue;
		}

		if (row < startrow) {
			if (tmp[i] == 0) {
				row++;
			}
			continue;
		}
		if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) {
			y += ystep;
			x = psx;
			int w = CalcStringWidth( &tmp[i + 1], NoColor );
			if (initials_rows > 0) {
				initials_rows--;
				x += initials_x;
				w += initials_x;
			}
			if (Alignment & IE_FONT_ALIGN_CENTER) {
				x = ( rgn.w - w ) / 2;
			} else if (Alignment & IE_FONT_ALIGN_RIGHT) {
				x = ( rgn.w - w );
			}
			continue;
		}
		unsigned char currChar = ( unsigned char ) tmp[i] - 1;
		if (initials && capital && enablecap) {
			x = initials->PrintInitial( x, y, rgn, currChar );
			initials_x = x;

			//how many more lines to be indented (one was already indented)
			initials_rows = (initials->maxHeight-1)/maxHeight;
			enablecap = false;
			continue;
		}
		video->BlitSpriteRegion( sprBuffer, size[currChar],
			x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn );
		if (cursor && ( i == curpos )) {
			video->BlitSprite( cursor, x + rgn.x,
				y + rgn.y, true, &rgn );
		}
		x += size[currChar].w;
	}
	if (cursor && ( curpos == len )) {
		video->BlitSprite( cursor, x + rgn.x,
			y + rgn.y, true, &rgn );
	}
	free( tmp );
}
예제 #12
0
파일: Font.cpp 프로젝트: joakimfong/gemrb
void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string,
	Palette* hicolor, ieByte Alignment, Font* initials,
	Sprite2D* cursor, unsigned int curpos, bool NoColor) const
{
	bool enablecap=false;
	int capital = 0;
	int initials_rows = 0;
	int last_initial_row = 0;
	int initials_x = 0;
	int initials_row = 0;
	ieWord currCap = 0;
	ieWord* tmp = NULL;
	size_t len = GetDoubleByteString(string, tmp);

	ieWord num_empty_rows = 0;

	if (initials && initials != this)
	{
		capital=1;
		enablecap=true;
		initials_rows = 1 + ((initials->maxHeight - 1) / maxHeight); // ceiling
		currCap = string[0];
		if ((startrow > 0 && initials_rows > 0) || (len > 0 && isspace(currCap))) { // we need to look back to get the cap
			while(isspace(currCap) && num_empty_rows < len){//we cant cap whiteSpace so keep looking
				currCap = string[++num_empty_rows];
				// WARNING: this assumes all preceeding whiteSpace is an empty line
			}
			last_initial_row = startrow - 1; // always the row before current since this cannot be the first row
			initials_rows = initials_rows - (startrow + 1) + num_empty_rows; // startrow + 1 because start row is 0 based, but initials_rows is 1 based
		}
	}

	unsigned int psx = IE_FONT_PADDING;
	Palette *pal = hicolor;
	if (!pal) {
		pal = palette;
	}

	Holder<Palette> blitPalette = pal;

	SetupString( tmp, rgn.w, NoColor, initials, enablecap );

	if (startrow) enablecap=false;
	int ystep;
	if (Alignment & IE_FONT_SINGLE_LINE) {
		ystep = CalcStringHeight(tmp, len, NoColor);
		if (!ystep) ystep = maxHeight;
	} else {
		ystep = maxHeight;
	}
	int x = psx, y = ystep;
	size_t w = CalcStringWidth( tmp, NoColor );
	if (Alignment & IE_FONT_ALIGN_CENTER) {
		x = ( rgn.w - w) / 2;
	} else if (Alignment & IE_FONT_ALIGN_RIGHT) {
		x = ( rgn.w - w ) - IE_FONT_PADDING;
	}
	if (Alignment & IE_FONT_ALIGN_MIDDLE) {
		int h = 0;
		for (size_t i = 0; i <= len; i++) {
			if (( tmp[i] == 0 ) || ( tmp[i] == '\n' ))
				h++;
		}
		h = h * ystep;
		y += ( rgn.h - h ) / 2;
	} else if (Alignment & IE_FONT_ALIGN_BOTTOM) {
		int h = 0;
		for (size_t i = 0; i <= len; i++) {
			if (( tmp[i] == 0 ) || ( tmp[i] == '\n' ))
				h++;
		}
		h = h * ystep;
		y += ( rgn.h - h ) - IE_FONT_PADDING;
	} else if (Alignment & IE_FONT_ALIGN_TOP) {
		y += IE_FONT_PADDING;
	}

	Video* video = core->GetVideoDriver();
	const Sprite2D* currGlyph;
	ieWord currChar = '\0';
	int row = 0;
	for (size_t i = 0; i < len; i++) {
		if (( tmp[i] ) == '[' && !NoColor) {
			i++;
			char tag[256];
			tag[0]=0;

			for (size_t k = 0; k < 256 && i<len; k++) {
				if (tmp[i] == ']') {
					tag[k] = 0;
					break;
				}
				tag[k] = tmp[i++];
			}

			if (strnicmp( tag, "capital=",8)==0) {
				sscanf( tag, "capital=%d", &capital);
				if (capital && (row>=startrow) ) {
					enablecap=true;
				}
				continue;
			}

			if (strnicmp( tag, "color=", 6 ) == 0) {
				unsigned int r,g,b;
				if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3)
					continue;
				const Color c = {(unsigned char)r, (unsigned char)g, (unsigned char)b, 0};
				Palette* newPal = core->CreatePalette( c, palette->back );
				blitPalette = newPal;
				gamedata->FreePalette( newPal );
				continue;
			}
			if (stricmp( tag, "/color" ) == 0) {
				blitPalette = pal;
				continue;
			}
			if (stricmp( "p", tag ) == 0) {
				psx = x;
				continue;
			}
			if (stricmp( "/p", tag ) == 0) {
				psx = IE_FONT_PADDING;
			}
			continue;
		}

		if (row < startrow) {
			if (tmp[i] == 0) {
				row++;
			}
			continue;
		}
		if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) {
			y += ystep;
			x = psx;
			size_t w = CalcStringWidth( &tmp[i + 1], NoColor );
			if (initials_rows > 0) {
				initials_rows--;
				x += initials_x;
				w += initials_x;
			}
			if (Alignment & IE_FONT_ALIGN_CENTER) {
				x = ( rgn.w - w ) / 2;
			} else if (Alignment & IE_FONT_ALIGN_RIGHT) {
				x = ( rgn.w - w );
			}
			continue;
		}
		currChar = tmp[i];
		if (initials && capital && enablecap) {
			currCap = currChar;
			x = initials->PrintInitial( x, y, rgn, currChar );
			initials_x = x;

			//how many more lines to be indented (one was already indented)
			initials_rows = (initials->maxHeight - 1) / maxHeight;
			initials_rows += num_empty_rows;
			initials_row = row;
			last_initial_row = initials_row;

			enablecap = false;
			continue;
		} else if (initials && currCap
				   && row > last_initial_row
				   && (row - num_empty_rows - initials_row) <= ((initials->maxHeight-1)/maxHeight)){
			// means this row doesnt have a cap, but a preceeding one did and its overlapping this row
			int initY = y;
			if (!num_empty_rows || row > num_empty_rows) {// num_empty_rows is for scrolling text areas
				initY = (y - (maxHeight * (row - initials_row - num_empty_rows)));
			}
			x = initials->PrintInitial( x, initY, rgn, currCap );
			initials_x = x;
			last_initial_row++;
			if (num_empty_rows && row <= num_empty_rows) continue;
			else x += psx;
		}
		if (i > 0) {
			// kerning
			x -= GetKerningOffset(tmp[i-1], currChar);
		}
		currGlyph = GetCharSprite(currChar);
		video->BlitSprite(currGlyph, x + rgn.x, y + rgn.y, true, &rgn, blitPalette.get());
		if (cursor && ( i == curpos )) {
			video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn );
		}
		x += currGlyph->Width;
	}
	if (cursor && ( curpos == len )) {
		video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn );
	}
	blitPalette = NULL;
	free( tmp );
}
예제 #13
0
파일: Font.cpp 프로젝트: joakimfong/gemrb
void Font::Print(Region cliprgn, Region rgn, const unsigned char* string,
	Palette* hicolor, ieByte Alignment, bool anchor, Font* initials,
	Sprite2D* cursor, unsigned int curpos, bool NoColor) const
{
	int capital = (initials) ? 1 : 0;

	unsigned int psx = IE_FONT_PADDING;
	Palette* pal = hicolor;
	if (!pal) {
		pal = palette;
	}
	if (initials==this) {
		initials = NULL;
	}

	Holder<Palette> blitPalette = pal;
	ieWord* tmp = NULL;
	size_t len = GetDoubleByteString(string, tmp);
	while (len > 0 && (tmp[len - 1] == '\n' || tmp[len - 1] == '\r')) {
		// ignore trailing newlines
		tmp[len - 1] = 0;
		len--;
	}

	SetupString( tmp, rgn.w, NoColor, initials, capital );
	int ystep;
	if (Alignment & IE_FONT_SINGLE_LINE) {
		ystep = CalcStringHeight(tmp, len, NoColor);
		if (!ystep) ystep = maxHeight;
	} else {
		ystep = maxHeight;
	}
	int x = psx, y = ystep;
	Video* video = core->GetVideoDriver();

	if (Alignment & IE_FONT_ALIGN_CENTER) {
		size_t w = CalcStringWidth( tmp, NoColor );
		x = ( rgn.w - w ) / 2;
	} else if (Alignment & IE_FONT_ALIGN_RIGHT) {
		size_t w = CalcStringWidth( tmp, NoColor );
		x = ( rgn.w - w ) - IE_FONT_PADDING;
	}

	if (Alignment & IE_FONT_ALIGN_MIDDLE) {
		int h = 0;
		for (size_t i = 0; i <= len; i++) {
			if (tmp[i] == 0)
				h++;
		}
		h = h * ystep;
		y += ( rgn.h - h ) / 2;
	} else if (Alignment & IE_FONT_ALIGN_BOTTOM) {
		int h = 0;
		for (size_t i = 0; i <= len; i++) {
			if (tmp[i] == 0)
				h++;
		}
		h = h * ystep;
		y += ( rgn.h - h ) - IE_FONT_PADDING;
	} else if (Alignment & IE_FONT_ALIGN_TOP) {
		y += IE_FONT_PADDING;
	}

	ieWord currChar = '\0';
	const Sprite2D* currGlyph = NULL;
	for (size_t i = 0; i < len; i++) {
		if (( tmp[i] ) == '[' && !NoColor) {
			i++;
			char tag[256];
			tag[0]=0;
			for (size_t k = 0; k < 256 && i<len; k++) {
				if (tmp[i] == ']') {
					tag[k] = 0;
					break;
				}
				tag[k] = tmp[i++];
			}

			if (strnicmp( tag, "capital=",8)==0) {
				sscanf( tag, "capital=%d", &capital);
				continue;
			}

			if (strnicmp( tag, "color=", 6 ) == 0) {
				unsigned int r,g,b;
				if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3)
					continue;
				const Color c = {(unsigned char)r, (unsigned char)g, (unsigned char)b, 0};
				Palette* newPal = core->CreatePalette( c, palette->back );
				blitPalette = newPal;
				gamedata->FreePalette( newPal );
				continue;
			}
			if (stricmp( tag, "/color" ) == 0) {
				blitPalette = pal;
				continue;
			}
			if (stricmp( "p", tag ) == 0) {
				psx = x;
				continue;
			}
			if (stricmp( "/p", tag ) == 0) {
				psx = IE_FONT_PADDING;
				continue;
			}
			continue;
		}

		if (tmp[i] == 0) {
			y += ystep;
			x = psx;
			size_t w = CalcStringWidth( &tmp[i + 1], NoColor );
			if (Alignment & IE_FONT_ALIGN_CENTER) {
				x = ( rgn.w - w ) / 2;
			} else if (Alignment & IE_FONT_ALIGN_RIGHT) {
				x = ( rgn.w - w );
			}
			continue;
		}
		currChar = tmp[i];
		currGlyph = GetCharSprite(currChar);
		if (initials && capital) {
			x = initials->PrintInitial( x, y, rgn, currChar );
			continue;
		}

		if (i > 0) {
			// kerning
			x -= GetKerningOffset(tmp[i-1], currChar);
		}

		video->BlitSprite(currGlyph, x + rgn.x, y + rgn.y, anchor, &cliprgn, blitPalette.get());

		if (cursor && ( curpos == i ))
			video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn );
		x += currGlyph->Width;
	}
	if (cursor && ( curpos == len )) {
		video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn );
	}
	blitPalette = NULL;
	free( tmp );
}
예제 #14
0
/** Draws the Control on the Output Display */
void WorldMapControl::Draw(unsigned short XWin, unsigned short YWin)
{
	WorldMap* worldmap = core->GetWorldMap();
	if (!Width || !Height) {
		return;
	}
	if(!Changed)
		return;
	Changed = false;
	Video* video = core->GetVideoDriver();
	Region r( XWin+XPos, YWin+YPos, Width, Height );
	Region clipbackup;
	video->GetClipRect(clipbackup);
	video->SetClipRect(&r);
	video->BlitSprite( worldmap->GetMapMOS(), MAP_TO_SCREENX(0), MAP_TO_SCREENY(0), true, &r );

	unsigned int i;
	unsigned int ec = worldmap->GetEntryCount();
	for(i=0;i<ec;i++) {
		WMPAreaEntry *m = worldmap->GetEntry(i);
		if (! (m->GetAreaStatus() & WMP_ENTRY_VISIBLE)) continue;

		int xOffs = MAP_TO_SCREENX(m->X);
		int yOffs = MAP_TO_SCREENY(m->Y);
		Sprite2D* icon = m->GetMapIcon(worldmap->bam);
		if( icon ) {
			if (m == Area) {
				Palette *pal = icon->GetPalette();
				icon->SetPalette(pal_selected);
				video->BlitSprite( icon, xOffs, yOffs, true, &r );
				icon->SetPalette(pal);
				pal->Release();
			} else {
				video->BlitSprite( icon, xOffs, yOffs, true, &r );
			}
			video->FreeSprite( icon );
		}

		if (AnimPicture && !strnicmp(m->AreaResRef, currentArea, 8) ) {
			video->BlitSprite( AnimPicture, xOffs, yOffs, true, &r );
		}
	}

	// Draw WMP entry labels
	if (ftext==NULL) {
		video->SetClipRect(&clipbackup);
		return;
	}
	for(i=0;i<ec;i++) {
		WMPAreaEntry *m = worldmap->GetEntry(i);
		if (! (m->GetAreaStatus() & WMP_ENTRY_VISIBLE)) continue;
		Sprite2D *icon=m->GetMapIcon(worldmap->bam);
		int h=0,w=0,xpos=0,ypos=0;
		if (icon) {
			h=icon->Height;
			w=icon->Width;
			xpos=icon->XPos;
			ypos=icon->YPos;
			video->FreeSprite( icon );
		}

		Region r2 = Region( MAP_TO_SCREENX(m->X-xpos), MAP_TO_SCREENY(m->Y-ypos), w, h );
		if (!m->GetCaption())
			continue;

		int tw = ftext->CalcStringWidth( (unsigned char*)m->GetCaption() ) + 5;
		int th = ftext->maxHeight;
		
		Palette* text_pal = pal_normal;
		
		if (Area == m) {
			text_pal = pal_selected;
		} else {
			if (! (m->GetAreaStatus() & WMP_ENTRY_VISITED)) {
				text_pal = pal_notvisited;
			}
		}

		ftext->Print( Region( r2.x + (r2.w - tw)/2, r2.y + r2.h, tw, th ),
				( const unsigned char * ) m->GetCaption(), text_pal, 0, true );
	}
	video->SetClipRect(&clipbackup);
}