Example #1
0
void CTempAnnounceDlg::OnClickAdd()
{

	if (m_vecNoticeList.size() >= 15)
	{
		C179MsgBox::Show( this, NewMsgBox::MSGBOX_OK_ONE_STRING ,L"最多只能保存15条临时公告" );
		return;
	}

	CString strMessage;
	m_InputCtrl.GetWindowText(strMessage);
	int nLen = common::utility::stringhelper::CalcStringAsciiLength(strMessage.GetBuffer(0));
	if (nLen == 0 || nLen > 500)
	{
		C179MsgBox::Show( this, NewMsgBox::MSGBOX_OK_ONE_STRING ,L"内容不能为空,且不能超过500个字符" );
		return;
	}

	int nItem = m_savedAnnounceList.GetItemCount();

	NoticeInfo * pNoticeInfo = new NoticeInfo();
	pNoticeInfo->strContent = strMessage.GetBuffer(0);
	pNoticeInfo->stFont = GetFontInfo();
	//m_vecNoticeList[nItem] = stNoticeInfo;
	m_vecNoticeList.push_back(pNoticeInfo);

	SaveXML();

	m_savedAnnounceList.InsertItem(nItem,strMessage);
	m_savedAnnounceList.SetItemData(nItem,(DWORD_PTR)m_vecNoticeList[nItem]);
	m_InputCtrl.ClearInput();
	m_nCurSelItem = -1;
	m_pSkinEngine->SetSubSkinProp(GetSafeHwnd(), L"btnSaveModify", L"disabled", (CComVariant)true);

#if 0
	std::wstring strPath = common::utility::systemhelper::Get179AppPath()();
	strPath += L"\\123456";

	VecNoticeInfo noticelist;
	for (int i = 0; i < 10; i++)
	{
		NoticeInfo stNoticeInfo;
		stNoticeInfo.strTitle = common::utility::stringhelper::IntToString(i);
		stNoticeInfo.strContent = L"test";
		stNoticeInfo.stFont.font_color = GetFontInfo().crColor;
		stNoticeInfo.stFont.font_size = GetFontInfo().unFontSize;
		stNoticeInfo.stFont.font_style = GetFontInfo().unFontType;
		stNoticeInfo.stFont.font_type = GetFontInfo().strFontName;
		noticelist.push_back(stNoticeInfo);
	}


	CTempNoticeManager::SaveXML(strPath, L"test.xml", noticelist);
	strPath += L"\\test.xml";
	CTempNoticeManager::LoadXML(strPath, noticelist);
#endif
}
Example #2
0
TBFontFace *TBFontManager::CreateFontFace(const TBFontDescription &font_desc)
{
	assert(!HasFontFace(font_desc)); // There is already a font added with this description!

	TBFontInfo *fi = GetFontInfo(font_desc.GetID());
	if (!fi)
		return nullptr;

	if (fi->GetID() == 0) // Is this the test dummy font
	{
		if (TBFontFace *font = new TBFontFace(&m_glyph_cache, nullptr, font_desc))
		{
			if (m_fonts.Add(font_desc.GetFontFaceID(), font))
				return font;
			delete font;
		}
		return nullptr;
	}

	// Iterate through font renderers until we find one capable of creating a font for this file.
	for (TBFontRenderer *fr = m_font_renderers.GetFirst(); fr; fr = fr->GetNext())
	{
		if (TBFontFace *font = fr->Create(this, fi->GetFilename(), font_desc))
		{
			if (m_fonts.Add(font_desc.GetFontFaceID(), font))
				return font;
			delete font;
		}
	}
	return nullptr;
}
Example #3
0
void CTempAnnounceDlg::OnClickSave()
{
	if (m_nCurSelItem == -1)
	{
		return;
	}

	CString strMessage;
	m_InputCtrl.GetWindowText(strMessage);
	int nLen = common::utility::stringhelper::CalcStringAsciiLength(strMessage.GetBuffer(0));
	if (nLen == 0 || nLen > 500)
	{
		C179MsgBox::Show(this, NewMsgBox::MSGBOX_OK_ONE_STRING ,L"内容不能为空,且不能超过500个字符" );
		return;
	}

	NoticeInfo * pNoticeInfo = (NoticeInfo *)m_savedAnnounceList.GetItemData(m_nCurSelItem);
	if (pNoticeInfo != NULL)
	{
		pNoticeInfo->strContent = strMessage.GetBuffer(0);
		pNoticeInfo->stFont = GetFontInfo();
	}
	m_savedAnnounceList.SetItemText(m_nCurSelItem, 0, strMessage);

	m_InputCtrl.ClearInput();
	m_nCurSelItem = -1;
	m_pSkinEngine->SetSubSkinProp(GetSafeHwnd(), L"btnSaveModify", L"disabled", (CComVariant)true);

	SaveXML();
}
Example #4
0
static void centerstring (Rect r, Str255 s) {
	
	/*
	draw the string in the current font, size and style, centered inside
	the indicated rectangle.
	*/
	
	short rh = r.bottom - r.top;
	short rw = r.right - r.left;
	short h, v;
	FontInfo fi;
	
	GetFontInfo (&fi);
	
	ellipsize (s, rw); /*make sure it fits inside the rectangle, width-wise*/
	
	h = r.left + ((rw - StringWidth (s)) / 2);
	
	v = r.top + ((rh - (fi.ascent + fi.descent)) / 2) + fi.ascent;
	
	MoveTo (h, v);
	
	ClipRect (&r);
	
	DrawString (s);
	} /*centerstring*/
Example #5
0
/////////////////////////////////////////////////////////////
//
// DrawString
//
void
nsPluginInstance::DrawString(const unsigned char* text, 
                             short width, 
                             short height, 
                             short centerX, 
                             Rect drawRect)
{
	short length, textHeight, textWidth;
 
	if(text == NULL)
		return;
	
	length = strlen((char*)text);
	TextFont(1);
	TextFace(bold);
	TextMode(srcCopy);
	TextSize(12);
	
	FontInfo fontInfo;
	GetFontInfo(&fontInfo);

	textHeight = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
	textWidth = TextWidth(text, 0, length);
		
	if (width > textWidth && height > textHeight)
	{
		MoveTo(centerX - (textWidth >> 1), height >> 1);
		DrawText(text, 0, length);
	}		
Example #6
0
bool Compose(Font font, int chr, ComposedGlyph& cg)
{
	if(chr < 256 || chr > 256 + 128)
		return false;
	CGInfo f = gc_info[chr - 256];
	if(f.type == CG_NONE)
		return false;
	GlyphInfo gi = GetGlyphInfo(font, f.ascii);
	if(!gi.IsNormal())
		return false;
	int cw = gi.width;
	CommonFontInfo fi = GetFontInfo(font);
	gi = GetGlyphInfo(font, f.mark);
	if(!gi.IsNormal())
		return false;
	int mw = gi.width;
	cg.mark_font = font;
	cg.mark_pos.x = cg.mark_pos.y = 0;
	cg.basic_char = f.ascii;
	cg.mark_char = f.mark;
	if(cg.mark_char == CG_COMMA_UR && fi.fixedpitch)
		cg.mark_char = CG_CARON;
	if(cg.mark_char == CG_COMMA_T) {
		cg.mark_pos.y -= 3 * font.GetHeight() / 4;
		cg.mark_pos.x += 4 * cw / 10;
		if(font.IsItalic())
			cg.mark_pos.x += mw / 2;
	}
	else
	if(cg.mark_char == CG_COMMA_UR) {
		cg.mark_pos.y -= 2 * font.GetHeight() / 3;
		cg.mark_pos.x += cw - mw / 4;
		cg.mark_char = ',';
		if(font.IsItalic())
			cg.mark_pos.x += mw / 3;
	}
	else
	if(cg.mark_char == CG_COMMA_URI) {
		cg.mark_pos.y -= 2 * font.GetHeight() / 3;
		cg.mark_pos.x += cw - mw / 2;
		cg.mark_char = ',';
		if(font.IsItalic())
			cg.mark_pos.x += mw / 3;
	}
	else
	if(cg.mark_char != CG_STROKE) {
		if(cg.mark_char != CG_OGONEK && cg.mark_char != CG_CEDILLA && f.type == CG_CAPITAL) {
			cg.mark_font = font(9 * font.GetHeight() / 10);
			mw = GetGlyphInfo(cg.mark_font, f.mark).width;
			cg.mark_pos.y -= cg.mark_char == CG_RING_ABOVE ? font.GetHeight() / 19
			                            : font.GetHeight() / 10;
		}
		cg.mark_pos.x += (cw - mw) / 2;
		if(font.IsItalic())
			cg.mark_pos.x += mw / 5;
	}
	return true;
}
Example #7
0
void screenOpen(char *Title) {
    FontInfo fontInfo;
    int n;

    theWindow = GetNewWindow(screenWindow, nil, (WindowPtr)(-1));

    if ((Title != NULL) && (*Title != '\0')) {
        c2pstr(Title);
        SetWTitle(theWindow, Title);
        p2cstr(Title);
    }

    ShowWindow(theWindow);

    SetPort(theWindow);
    TextFont(monaco);
    TextSize(9);

    GetFontInfo(&fontInfo);
    fontHeight = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
    fontWidth = fontInfo.widMax;

    scrollRgn = NewRgn();

    screenWidth = (theWindow->portRect.right - theWindow->portRect.left - 10) /
        fontWidth;
    screenHeight = (theWindow->portRect.bottom - theWindow->portRect.top) /
        fontHeight;
    maxPosition = screenHeight * fontHeight;
    pausePosition = maxPosition - (currentPosition = fontHeight);

    SetRect(&scrollRect, theWindow->portRect.left, theWindow->portRect.top + fontInfo.descent,
        theWindow->portRect.right, theWindow->portRect.bottom);
    SetRect(&pauseRect, theWindow->portRect.left, pausePosition + fontInfo.descent,
        theWindow->portRect.right, theWindow->portRect.bottom);

    MoveTo(5, currentPosition);

    n = (sizeof(char *) + sizeof(short) + screenWidth) * screenHeight;

    screenLine = (char **)NewPtr(n);

    screenLength = (short *)&screenLine[screenHeight];
    screenImage = (char *)&screenLength[screenHeight];

    for (n = 0; n < screenHeight; n++) {
        screenLine[n] = &screenImage[n * screenWidth];
        screenLength[n] = 0;
    }

    startLine = endLine = 0;

    screenOptions = 0;

    return;
}
Example #8
0
void LCD_calcfont(Lcd *x)
{
	FontInfo	info;
	
	GetFontInfo(&info);

	x->f_width = info.widMax;
	x->f_ascent = info.ascent;
	x->f_descent = info.descent;
	x->f_height = info.ascent+info.descent;
	x->f_lineSpace = info.leading;
}
Example #9
0
char *GUIGetFontInfo( gui_window *wnd )
{
#ifndef __OS2_PM__
    LOGFONT             lf;

    if( GetObject( wnd->font, sizeof( LOGFONT ), (LPSTR) &lf ) == 0 ) {
        return( NULL );
    }
    return( GetFontInfo( &lf ) );
#else
    wnd = wnd;
    return( NULL );
#endif
}
Example #10
0
void CTempAnnounceDlg::OnCbnSelchangeComboFontsize()
{
	// TODO: 在此添加控件通知处理程序代码
	int nIndex = m_FontSizeCombo.GetCurSel() ;
	if ( nIndex != CB_ERR )
	{
		CString strTemp ;
		m_FontSizeCombo.GetLBText(nIndex, strTemp);
		int nFontSize = _wtoi( strTemp) ;
		if ( nFontSize != GetFontInfo().font_size )
		{
			m_InputCtrl.SetFontSize(nFontSize);
			CPersonalConfig::GetInstance()->SetTempMessageFont( m_InputCtrl.GetFontInfo() ) ;
		}
	}
}
Example #11
0
void CTempAnnounceDlg::OnCbnSelchangeComboFont()
{
	// TODO: 在此添加控件通知处理程序代码
	int nIndex = m_FontCombo.GetCurSel() ;
	if ( nIndex != CB_ERR )
	{
		CString strTemp;
		m_FontCombo.GetLBText(nIndex, strTemp);
		CString strFontName( GetFontInfo().font_type.c_str() ) ;
		if ( strTemp != strFontName )
		{
			m_InputCtrl.SetFontName(strTemp.GetBuffer(0));
			CPersonalConfig::GetInstance()->SetTempMessageFont( m_InputCtrl.GetFontInfo() ) ;
		}
	}
}
Example #12
0
int PASCAL WinMain( HINSTANCE instance, HINSTANCE previnstance,
                    LPSTR cmdline, int cmdshow )
/*******************************************************/
{
    HWND        hwnd;
    MSG         msg;
    WNDCLASS    wndclass;

    cmdline = cmdline;
    previnstance = previnstance;
#ifdef __WINDOWS_386__
    sprintf( ClassName,"Watzee%d",instance );
#else
    if( !previnstance ) {
#endif
        wndclass.style          = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc    = (LPVOID) WndProc;
        wndclass.cbClsExtra     = 0;
        wndclass.cbWndExtra     = 6 * sizeof( DWORD );
        wndclass.hInstance      = instance;
        wndclass.hIcon          = LoadIcon( instance, AppName );
        wndclass.hCursor        = LoadCursor( NULL, IDC_ARROW );
        wndclass.hbrBackground  = GetStockObject( WHITE_BRUSH );
        wndclass.lpszMenuName   = AppName;
        wndclass.lpszClassName  = ClassName;
        RegisterClass( &wndclass );
#ifndef __WINDOWS_386__
    }
#endif
    InitializeGameData();
    GetFontInfo();
    CreateFonts();
    hwnd = CreateWindow( ClassName, "WATZEE",
                         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                         CharWidth * 28 + CharWidth / 2, CharHeight * 28,
                         NULL, NULL, instance, NULL );
    GetDiceBitmaps( hwnd );
    ShowWindow( hwnd, cmdshow );
    UpdateWindow( hwnd );
    SendMessage( hwnd, WMW_START_NEW_GAME, 0, 0 );
    while( GetMessage( &msg, NULL, 0, 0 ) ) {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    return( msg.wParam );
}
Example #13
0
internal void
DEBUGTextLine(char *String) {
    debug_state *DebugState = DEBUGGetState();
    if (DebugState) {
        render_group *RenderGroup = DebugState->RenderGroup;

        loaded_font *Font = PushFont(RenderGroup, DebugState->FontID);

        if (Font) {
            hha_font *Info = GetFontInfo(RenderGroup->Assets, DebugState->FontID);

            DEBUGTextOutAt(V2(DebugState->LeftEdge,
                              DebugState->AtY - DebugState->FontScale * GetStartingBaselineY(DebugState->DebugFontInfo)), String);

            DebugState->AtY -= GetLineAdvanceFor(Info) * DebugState->FontScale;
        } else {
        }
    }
}
Example #14
0
/*	DisplayDialogCmd(theDialog, dlogItemNo, cmd)

	Displays the command in an IGOR-style dialog. See GBLoadWaveDialog.c
	for an example.
	
	dlogItemNo is the item number of the dialog item in which the command
	is to be displayed. On the Macintosh, this must be a user item. On Windows,
	it must be an EDITTEXT item.

	Thread Safety: DisplayDialogCmd is not thread-safe.
*/
void
DisplayDialogCmd(DialogPtr theDialog, int dlogItemNo, const char* cmd)
{
	WindowRef theWindow;
	CGrafPtr thePort;
	Rect box;
	int font, size;
	int lineHeight;
	FontInfo info;
	RgnHandle saveClipRgnH;
	
	theWindow = GetDialogWindow(theDialog);
	thePort = GetWindowPort(theWindow);
	
	font = GetPortTextFont(thePort);		// Save text characteristics.
	size = GetPortTextSize(thePort);

	TextFont(kFontIDMonaco);
	TextSize(9);
	GetFontInfo(&info);
	lineHeight = info.ascent + info.descent + info.leading;
	
	GetDBox(theDialog, dlogItemNo, &box);
	saveClipRgnH = NewRgn();
	if (saveClipRgnH != NULL) {
		GetClip(saveClipRgnH);
		ClipRect(&box);
		InsetRect(&box, 2, 2);
		EraseRect(&box);
		if (*cmd != 0) {
			MoveTo(box.left+2, box.top + info.ascent + 2);
			DrawDialogCmd(cmd, lineHeight);
		}
		SetClip(saveClipRgnH);
		DisposeRgn(saveClipRgnH);
	}

	TextFont(font);									// Restore font, size, style.
	TextSize(size);
}
Example #15
0
char *GUIGetFontFromUser( char *fontinfo )
{
#ifndef __OS2_PM__
    LOGFONT     lf;
    HFONT       font;

    font = NULL;
    if( fontinfo != NULL ) {
        GetLogFontFromString( &lf, fontinfo );
        font = CreateFontIndirect( &lf );
        fontinfo = NULL;
    }
    if( GUIChooseFont( font, &lf, NULL ) ) {
        fontinfo = GetFontInfo( &lf );
    }
    if( font != NULL ) {
        DeleteObject( font );
    }
    return( fontinfo );
#else
    fontinfo = fontinfo;
    return( NULL );
#endif
}
/* ------------ Local code */
static void add_overhead_thumbnail(
    FileSpecifier &File)
{
    PicHandle picture;
    PicHandle preview;
    RgnHandle clip_region;
    FontInfo info;
    short text_x, text_y;
    short text_length;
    Str255 temporary;
    GWorldPtr old_gworld;
    GDHandle old_device;
    struct overhead_map_data overhead_data;
    Rect bounds;
    AEDesc aeFileSpec;
    FSSpec *SpecPtr;

    // Skip all this if there's no nav services to install the preview
    if(!machine_has_nav_services() || NavLibraryVersion() < kNavServicesVersion_2_0)
        return;

    GetGWorld(&old_gworld, &old_device);
    SetGWorld(world_pixels, (GDHandle) NULL);

    // Note well. We're using world_pixels to create our thumbnail pict within.
    // If world_pixels is runing as a postage stamp (low-res + small display space)
    // Then it is actually smaller than the size we're looking to build a thumbnail
    // within. But seeing as we're generating pict images and using drawing commands
    // instead of bit-wise operations. It all works out.

    /* Create the bounding rectangle */
    SetRect(&bounds, 0, 0, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);

    /* Start recording.. */
    picture= OpenPicture(&bounds);

    PaintRect(&bounds);

    overhead_data.scale= OVERHEAD_MAP_MINIMUM_SCALE;
    overhead_data.origin.x= local_player->location.x;
    overhead_data.origin.y= local_player->location.y;
    overhead_data.half_width= RECTANGLE_WIDTH(&bounds)/2;
    overhead_data.half_height= RECTANGLE_HEIGHT(&bounds)/2;
    overhead_data.width= RECTANGLE_WIDTH(&bounds);
    overhead_data.height= RECTANGLE_HEIGHT(&bounds);
    overhead_data.mode= _rendering_saved_game_preview;

    _render_overhead_map(&overhead_data);

    RGBForeColor(&rgb_black);
    PenSize(1, 1);
    TextFont(0);
    TextFace(normal);
    TextSize(0);

    ClosePicture();

    // JTP: Add Nav Services style preview
    SetRect(&bounds, 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT);
    preview= OpenPicture(&bounds);

    SetRect(&bounds, PREVIEW_IMAGE_X, PREVIEW_IMAGE_Y,
            THUMBNAIL_WIDTH + PREVIEW_IMAGE_X, THUMBNAIL_HEIGHT + PREVIEW_IMAGE_Y);
    clip_region= NewRgn();
    GetClip(clip_region);
    ClipRect(&bounds);
    DrawPicture(picture, &bounds);
    SetClip(clip_region);

    /* Center the text in the rectangle */
    // LP: Classic doesn't have this function
#ifdef TARGET_API_MAC_CARBON
    CopyCStringToPascal(static_world->level_name, temporary);
#else
    strncpy((char *)temporary,static_world->level_name,LEVEL_NAME_LENGTH);
    c2pstr((char *)temporary);
#endif
    // LP: fix to allow lengths more than 127 bytes (not really necessary, but...)
    text_length = *ptemporary;
    TruncText(PREVIEW_WIDTH, (char *)temporary+1, &text_length, smTruncEnd);
    *ptemporary = text_length;

    GetFontInfo(&info);
    text_y= PREVIEW_HEIGHT - info.descent;
    text_x= PREVIEW_LABEL_X + (PREVIEW_WIDTH-StringWidth(temporary))/2;
    MoveTo(text_x, text_y);
    DrawString(temporary);

    ClosePicture();

    // This requires NavServices 2.0, what's the inline check?
    // From FSS get a AEDesc
    OSStatus err;
    SpecPtr = &File.GetSpec();
    err = AECreateDesc(typeFSS, SpecPtr, sizeof(FSSpec), &aeFileSpec);

    HLock((Handle)preview);
    err = NavCreatePreview(&aeFileSpec, 'PICT', *preview, GetHandleSize((Handle)preview));
    HUnlock((Handle)preview);

    AEDisposeDesc(&aeFileSpec);
    KillPicture(preview);
    KillPicture(picture);
    DisposeRgn(clip_region);

    SetGWorld(old_gworld, old_device);
}
Example #17
0
LRESULT CTempAnnounceDlg::OnSkinMessage(WPARAM wParam, LPARAM lParam)
{
    switch(wParam)
	{
	case SKIN_ON_CLICK_JIACU:
		{
			if (1 == lParam)//选择加粗
			{
				m_InputCtrl.SetFontBold(true);				
			}
			else//取消加粗
			{
				m_InputCtrl.SetFontBold(false);
			}
			CPersonalConfig::GetInstance()->SetTempMessageFont( m_InputCtrl.GetFontInfo() ) ;
		}
        break;
	case SKIN_ON_CLICK_XIETI:
		{
			if (1 == lParam)//选择斜体
			{
				m_InputCtrl.SetFontItalic(true);
			}
			else//取消斜体
			{
				m_InputCtrl.SetFontItalic(false);
			}
			CPersonalConfig::GetInstance()->SetTempMessageFont( m_InputCtrl.GetFontInfo() ) ;
		}
		break;
	case SKIN_ON_CLICK_UNDERLINE:
		{ 
			if (1 == lParam)//选择下划线
			{
				m_InputCtrl.SetFontUnderLine(true);
			}
			else//取消下划线
			{
				m_InputCtrl.SetFontUnderLine(false);
			}
			CPersonalConfig::GetInstance()->SetTempMessageFont( m_InputCtrl.GetFontInfo() ) ;
		}
		break;
	case SKIN_ON_CLICK_FONT_COLOR:
		{
			CColorDialog ColorDlg(GetFontInfo().font_color );
			if ( ColorDlg.DoModal() == IDOK )
			{
				m_InputCtrl.SetFontColor(ColorDlg.GetColor());
			}
			CPersonalConfig::GetInstance()->SetTempMessageFont( m_InputCtrl.GetFontInfo() ) ;
		}
		break;
	case SKIN_ON_CLICK_BTN_PUBLISH:
		{
			PublishTempAnnounce();
		}
		break;
	case SKIN_ON_CLICK_BTN_ADD:
		{
			OnClickAdd();
		}
		break;
	case SKIN_ON_CLICK_BTN_SAVE_MODIFY:
		{
			OnClickSave();
		}
		break;
	case SKIN_ON_CLICK_BTN_DELETE:
		{
			OnClickDelete();
		}
		break;
	default: break;
	}

    return TRUE;
}
Example #18
0
static
void draw_string(int x, int y, int width, int height, Str255 chars)
{
  FontInfo info;
  GWorldPtr fromworld, toworld;
  CGrafPtr onport, saveport;
  GDHandle savedevice;
  int txFont, txFace, txSize;
  Rect fromrect, torect, onrect;
  PixMapHandle frompix, topix, onpix;
  int *from, *to, from_width, to_width;
  register int descent, w = 0, h = 0;
  register int i, j, ii = 0, jj = 0;

  if (p->path != 0)
    {
      GetFontInfo(&info);
      height += 8;
      descent = info.descent;

      switch (p->path)
	{
	  case 1: x -= height-descent; y -= width; w = height; h = width; break;
	  case 2: x -= width; y -= descent; w = width; h = height; break;
	  case 3: x -= descent; w = height; h = width; break;
	}

      GetGWorld(&saveport, &savedevice);
      txFont = GetPortTextFont(saveport);
      txFace = GetPortTextFace(saveport);
      txSize = GetPortTextSize(saveport);

      onport = p->port;
      onpix = GetPortPixMap(onport);

      fromrect.left = 0;
      fromrect.right = width;
      fromrect.top = 0;
      fromrect.bottom = height;
      NewGWorld(&fromworld, 32, &fromrect, NULL, NULL, 0);
      SetGWorld(fromworld, NULL);
	
      frompix = GetGWorldPixMap(fromworld);
      from = (int *) GetPixBaseAddr(frompix);
      from_width = GetPixRowBytes(frompix) / 4;

      LockPixels(frompix);

      EraseRect(&fromrect);
      MoveTo(0, height - descent);
      TextFont(txFont);
      TextFace(txFace);
      TextSize(txSize);
      DrawString(chars);

      torect.left = 0;
      torect.right = w;
      torect.top = 0;
      torect.bottom = h;
      NewGWorld(&toworld, 32, &torect, NULL, NULL, 0);

      topix = GetGWorldPixMap(toworld);
      to = (int *) GetPixBaseAddr(topix);
      to_width = GetPixRowBytes(topix) / 4;

      LockPixels(topix);
      for (i = 0; i < width; i++)
	{
	  for (j = 0; j < height; j++)
	    {
	      switch (p->path)
		{
		  case 1: ii = j; jj = h - i - 1; break;
		  case 2: ii = w - i - 1; jj = h - j - 1; break;
		  case 3: ii = w - j - 1; jj = i; break;
		}
	      to[jj * to_width + ii] = from[j * from_width + i];
	    }
	}
      UnlockPixels(topix);
      UnlockPixels(frompix);

      onrect.left = x;
      onrect.right = x + w;
      onrect.top = y;
      onrect.bottom = y + h;

      SetGWorld(saveport, savedevice);

      SetPort(onport);
      LockPixels(topix);
      CopyBits(
	(BitMap *) *topix, (BitMap *) *onpix, &torect, &onrect, srcOr, NULL);
      UnlockPixels(topix);
	
      DisposeGWorld(toworld);
      DisposeGWorld(fromworld);
    }
  else
    {
      MoveTo(x, y);
      DrawString(chars);
    }
}