home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Power 1996 October
/
MACPOWER-1996-10.ISO.7z
/
MACPOWER-1996-10.ISO
/
MacPowerオリジナル
/
キョービのプログラマ
/
BigText.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-08-13
|
16KB
|
583 lines
/*----------------------------------------------Written by T.Matsubara
********** * * * * * * *
* * * *********** * * * *
* *********** *********** * * ********* **********
********* * * * ****** * * * *
* * * * * * * * * * *
* * * * * * * * **** * *
********* * * * * *********** ******* * * * *
* * * * * * * * *
* * * * * * * * * * *
* * * ** ** * * * ** * **
********** * * ** ** ** *********** * * *
** * *
** * * * ****** *
******** ******* * *
* * * ***** *
* * * * * ******** *
* * * ** * * * *
* * * * * ** *
* ******* * * * ***
** * * ** ** ***** *
** ** ** *
***** * ******* *
* * * *
* * ** **** * *** * * *** ***
***** * * * * * * * * * * *
* * * * * * * * * * * *
* * * * * * ***** * * *
* * * * * * * * * * *
* * * * * * * * * * * * *
***** * **** * *** * * ** * ***
*
* *
***
---------------------------------------------------------------------*/
/*------------- include non-standard header file -------------*/
#include <QDOffscreen.h>
/*------------- define Dialog Item's Index Number -------------*/
#define K_QUIT 1
#define K_COPY 2
#define K_FONT 3
#define K_SIZE 4
#define K_CHAR 5
#define K_TEXT 6
#define K_RESULT 7
/*------------- define char popup menu's item number -------------*/
#define K_OTHER_CHAR 6
#define K_KANJI_START 7
/*------------- define Offscreen gworld size -------------*/
#define K_OFF_WIDTH 512
#define K_OFF_HEIGHT 120
/*------------- prototypes -------------*/
/*------------- main -------------*/
void main(void);
/*------------- initialize -------------*/
void do_init_rom(void);
int do_init_appl(void);
long install_apple_events_handler(void);
/*------------- process apple events -------------*/
pascal OSErr ae_launch(AppleEvent * theAppleEvent, AppleEvent * replyAppleEvent, long refCon);
pascal OSErr ae_opendoc(AppleEvent * theAppleEvent, AppleEvent * replyAppleEvent, long refCon);
pascal OSErr ae_print(AppleEvent * theAppleEvent, AppleEvent * replyAppleEvent, long refCon);
pascal OSErr ae_quit(AppleEvent * theAppleEvent, AppleEvent * replyAppleEvent, long refCon);
/*------------- event loop -------------*/
void do_main_event_loop(void);
/*------------- management menus -------------*/
void do_menu(long menu_and_item);
void get_menu_options(void);
void choose_other_char(void);
/*------------- Utility routines -------------*/
Handle get_ditm_handle(DialogPtr xdp, short itemnum);
short get_ctl_value(short itemnum);
void set_ctl_value(short itemnum, short value);
/*------------- draw big text -------------*/
pascal void draw_user_item(DialogPtr dp, short itemnum);
/*------------- create big text -------------*/
void create_big_text(void);
void add_one_char(char what_char);
void put_big_text_into_scrap(void);
/*------------- GLOBAL VAR -------------*/
Boolean exit_program = false;
MenuHandle applemenu, filemenu, editmenu;
MenuHandle pop_font, pop_size, pop_char;
AEEventHandlerUPP upp_launch, upp_opendoc, upp_print, upp_quit;
DialogPtr dp;
CGrafPtr off;
Boolean jap_script_available;
Handle big_text_hdl;
Rect big_text_area;
short cur_font_choosed;
short cur_font_id;
short cur_size_choosed;
long cur_size;
short cur_char_choosed;
Boolean cur_char_is_kanji;
short cur_kanji_char;
char cur_ascii_char;
short kanji_space = 0x8140;
short monaco_font_id;
char other_char_is_kanji = false;
char other_ascii_char = '*';
short other_kanji_char;
/*------------- Implementation -------------*/
/*------------- main -------------*/
void main(void)
{
do_init_rom();
install_apple_events_handler();
if(do_init_appl() == 0) {
do_main_event_loop();
}
}
/*------------- initialize -------------*/
void do_init_rom(void)
{
MaxApplZone();
MoreMasters();
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(nil);
FlushEvents(everyEvent,0);
InitCursor();
DrawMenuBar();
}
int do_init_appl(void)
{
short kind;
Handle h;
Rect r;
UserItemUPP user_item_upp;
CGrafPtr saved_port;
GDHandle saved_gdh;
short i, n_menu_items;
Str255 str;
/* get font id of monaco */
GetFNum("¥pMonaco", &monaco_font_id);
/* check japanease font */
h = GetResource('itlb', 1);
jap_script_available = (h != 0);
/* setup menus */
pop_font = GetMenu(131);
AddResMenu(pop_font, 'FONT');
pop_size = GetMenu(132);
pop_char = GetMenu(133);
InsertMenu(applemenu = GetMenu(128), 0);
InsertMenu(filemenu = GetMenu(129), 0);
InsertMenu(editmenu = GetMenu(130), 0);
AddResMenu(applemenu, 'DRVR');
DrawMenuBar();
if(!jap_script_available) {
// japanease font not found.
// delete kanji from japanease menu.
n_menu_items = CountMItems(pop_char);
for(i=K_KANJI_START; i<=n_menu_items; i++)
DelMenuItem(pop_char, K_KANJI_START);
}
/* setup dialog */
dp = GetNewDialog(128, nil, (WindowPtr) -1);
if(dp == nil) return -1;
user_item_upp = NewUserItemProc(draw_user_item);
GetDItem(dp, K_RESULT, &kind, &h, &big_text_area);
SetDItem(dp, K_RESULT, kind, (void*)user_item_upp, &big_text_area);
set_ctl_value(K_FONT, 1);
set_ctl_value(K_SIZE, 4);
set_ctl_value(K_CHAR, 1);
InsetRect(&big_text_area, -1, -1);
if(jap_script_available) {
GetIndString(str, 128, 1);
} else {
GetIndString(str, 128, 2);
}
SetIText(get_ditm_handle(dp, K_TEXT), str);
SelIText(dp, K_TEXT, 0, 1000);
/* setup offscreen */
GetGWorld(&saved_port, &saved_gdh);
SetRect(&r, 0, 0, K_OFF_WIDTH, K_OFF_HEIGHT);
if(NewGWorld(&off, 8, &r, nil, nil, nil) == 0) {
LockPixels(GetGWorldPixMap(off));
SetGWorld(off, nil);
EraseRect(&off->portRect);
} else {
off = nil;
}
SetGWorld(saved_port, saved_gdh);
if(off == nil) return -1;
/* setup big text buffer */
big_text_hdl = NewHandle(0);
return 0;
}
long install_apple_events_handler(void)
{
OSErr err;
long resp, rv;
rv = -1;
err = Gestalt(gestaltAppleEventsAttr, &resp);
if ((err == noErr) && (resp & (31 - gestaltAppleEventsPresent))) {
upp_launch = NewAEEventHandlerProc(ae_launch);
upp_opendoc = NewAEEventHandlerProc(ae_opendoc);
upp_print = NewAEEventHandlerProc(ae_print);
upp_quit = NewAEEventHandlerProc(ae_quit);
err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, upp_launch, 0, false);
err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, upp_opendoc, 0, false);
err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, upp_print, 0, false);
err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, upp_quit, 0, false);
rv = err;
}
return rv;
}
/*------------- process apple events -------------*/
pascal OSErr ae_launch(AppleEvent * theAppleEvent, AppleEvent * replyAppleEvent, long refCon)
{ return noErr; }
pascal OSErr ae_opendoc(AppleEvent * theAppleEvent, AppleEvent * replyAppleEvent, long refCon)
{ return errAEEventNotHandled; }
pascal OSErr ae_print(AppleEvent * theAppleEvent, AppleEvent * replyAppleEvent, long refCon)
{ return errAEEventNotHandled; }
pascal OSErr ae_quit(AppleEvent * theAppleEvent, AppleEvent * replyAppleEvent, long refCon)
{ exit_program = true; return noErr; }
/*------------- event loop -------------*/
void do_main_event_loop(void)
{
EventRecord an_event;
WindowPtr clicked_wp;
short itemhit;
DialogPtr clicked_dialog;
/* load and setup dialogs */
ShowWindow(dp);
SetPort(dp);
/* event loop */
create_big_text();
do {
WaitNextEvent(everyEvent, &an_event, 60, nil);
switch(an_event.what) {
case kHighLevelEvent: AEProcessAppleEvent(&an_event); break;
case mouseDown:
switch(FindWindow(an_event.where, &clicked_wp)) {
case inDrag:
DragWindow(clicked_wp, an_event.where, &qd.screenBits.bounds);
break;
case inMenuBar:
do_menu(MenuSelect(an_event.where));
}
break;
case keyDown:
case autoKey:
if((an_event.modifiers & cmdKey) != 0)
do_menu(MenuKey((char)(an_event.message & charCodeMask)));
break;
}
if(IsDialogEvent(&an_event)) {
if(DialogSelect(&an_event, &clicked_dialog, &itemhit)) {
switch(itemhit) {
case K_QUIT:
exit_program = true;
break;
case K_COPY:
put_big_text_into_scrap();
break;
case K_CHAR:
if(get_ctl_value(K_CHAR) == K_OTHER_CHAR)
choose_other_char();
create_big_text();
break;
default:
create_big_text();
break;
}
}
}
} while(!exit_program);
}
/*------------- management menus -------------*/
void do_menu(long menu_and_item)
{
short itemnum;
Str255 da_name;
itemnum = LoWord(menu_and_item);
switch(HiWord(menu_and_item)) {
case 128: // apple menu
switch(itemnum) {
case 1:
Alert(1280, nil);
break;
default:
GetItem(applemenu, itemnum, da_name);
OpenDeskAcc(da_name);
break;
}
break;
case 129: // file menu
exit_program = true;
break;
case 130: // edit menu
switch(itemnum) {
case 8: // select all
SelIText(dp, K_TEXT, 0, 1000);
break;
case 10: // Copy big text
put_big_text_into_scrap();
break;
default: // DialogSelect's job
break;
}
break;
}
HiliteMenu(0);
}
void get_menu_options(void)
{
Str255 str;
cur_font_choosed = get_ctl_value(K_FONT);
cur_size_choosed = get_ctl_value(K_SIZE);
cur_char_choosed = get_ctl_value(K_CHAR);
GetItem(pop_font, cur_font_choosed, str);
GetFNum(str, &cur_font_id);
GetItem(pop_size, cur_size_choosed, str);
StringToNum(str, &cur_size);
if(cur_char_choosed == K_OTHER_CHAR) {
cur_char_is_kanji = other_char_is_kanji;
cur_ascii_char = other_ascii_char;
cur_kanji_char = other_kanji_char;
} else {
GetItem(pop_char, cur_char_choosed, str);
if(str[1] == ' ') {
cur_char_is_kanji = false;
cur_ascii_char = str[2];
} else {
cur_char_is_kanji = true;
BlockMove((void*)&str[1], (void*)&cur_kanji_char, 2);
}
}
}
void choose_other_char(void)
{
DialogPtr other_dp;
GrafPtr saved_port;
short itemhit;
short kind;
Handle h;
Rect r;
Str255 str;
GetPort(&saved_port);
other_dp = GetNewDialog(129, nil, (WindowPtr) -1);
if(other_dp == nil) return;
if(other_char_is_kanji) {
str[0] = 2;
BlockMove((void*)&other_kanji_char, (void*)&str[1], 2);
} else {
str[0] = 1;
str[1] = other_ascii_char;
}
SetIText(get_ditm_handle(other_dp, 3), str);
ShowWindow(other_dp);
SetPort(other_dp);
SelIText(other_dp, 3, 0, 1000);
for(itemhit = 0; itemhit != 1;) {
GetDItem(other_dp, 1, &kind, &h, &r);
InsetRect(&r, -4, -4);
PenSize(3, 3);
FrameRoundRect(&r, 16, 16);
PenSize(1, 1);
ModalDialog(nil, &itemhit);
GetIText(get_ditm_handle(other_dp, 3), str);
switch(itemhit) {
case 1:
if(str[0] <= 0) itemhit = 0;
else if(str[0] > 2) itemhit = 0;
else {
switch(CharByte((void*)&str[1], 0)) {
case 0: // ascii char
if(str[0] != 1) {
itemhit = 0;
} else {
other_char_is_kanji = false;
other_ascii_char = str[1];
}
break;
case -1: // first byte of kanji
if(str[0] != 2) {
itemhit = 0;
} else {
other_char_is_kanji = true;
BlockMove(&str[1], (void*)&other_kanji_char, 2);
}
break;
default: // error.
itemhit = 0;
break;
}
}
if(itemhit == 0) {
SysBeep(1);
SelIText(other_dp, 3, 0, 1000);
}
break;
}
}
DisposDialog(other_dp);
SetPort(saved_port);
}
/*------------- Utility routines -------------*/
Handle get_ditm_handle(DialogPtr xdp, short itemnum)
{
short kind;
Handle h;
Rect r;
GetDItem(xdp, itemnum, &kind, &h, &r);
return h;
}
short get_ctl_value(short itemnum)
{
return GetCtlValue((ControlHandle)get_ditm_handle(dp, itemnum));
}
void set_ctl_value(short itemnum, short value)
{
SetCtlValue((ControlHandle)get_ditm_handle(dp, itemnum), value);
}
/*------------- draw big text -------------*/
pascal void draw_user_item(DialogPtr dp, short itemnum)
{
GrafPtr saved_port;
Rect r;
long big_text_size, i, j, k, y;
Ptr p;
FontInfo cur_font_info;
GetPort(&saved_port);
SetPort(dp);
if(cur_char_is_kanji) {
TextFont(applFont);
TextSize(12);
} else {
TextFont(monaco_font_id);
TextSize(9);
}
FrameRect(&big_text_area);
r = big_text_area;
InsetRect(&r, 1, 1);
EraseRect(&r);
big_text_size = GetHandleSize(big_text_hdl);
HLock(big_text_hdl);
p = *big_text_hdl;
GetFontInfo(&cur_font_info);
y = r.top + cur_font_info.ascent + cur_font_info.descent;
for(i=0, j=0; i<big_text_size; i++) {
if( (i == (big_text_size-1)) || (p[i] == 0x0d) ) {
k = i - j;
if(k > 0) {
MoveTo(r.left, y);
DrawText(p, j, k);
}
y += cur_font_info.ascent + cur_font_info.descent + cur_font_info.leading;
j = i + 1;
}
}
HUnlock(big_text_hdl);
TextFont(applFont);
TextSize(12);
SetPort(saved_port);
}
/*------------- create big text -------------*/
void create_big_text(void)
{
#define K_WIDTH 76 // big text width
CGrafPtr saved_port;
GDHandle saved_gdh;
FontInfo cur_font_info;
short i, j, k, n_chars, n_lines;
short width, off_rowbytes, x, y, line_height, space_counter;
char *pix;
Str255 str;
get_menu_options();
SetHandleSize(big_text_hdl, 0);
GetGWorld(&saved_port, &saved_gdh);
/* text > off */
SetGWorld(off, nil);
TextFont(cur_font_id);
TextSize(cur_size);
GetFontInfo(&cur_font_info);
GetIText(get_ditm_handle(dp, K_TEXT), str);
EraseRect(&off->portRect);
n_chars = str[0];
line_height = cur_font_info.ascent + cur_font_info.descent;
y = cur_font_info.ascent;
n_lines = 0;
for(i=j=1; i<=n_chars; i++) {
if( (i == n_chars) || (str[i] == 0x0d) ) {
k = i - j;
if(str[i] != 0x0d) k++;
if(k > 0) {
MoveTo(0, y);
DrawText(str, j, k);
}
j = i + 1;
y += line_height;
n_lines++;
}
}
line_height *= n_lines;
/* off > big text */
off_rowbytes = (**GetGWorldPixMap(off)).rowBytes;
off_rowbytes &= 0x7fff;
pix = (char*)GetPixBaseAddr(GetGWorldPixMap(off));
if(cur_char_is_kanji) width = K_WIDTH / 2;
else width = K_WIDTH;
for(y=0; y<line_height; y++) {
space_counter = 0;
for(x=0; x<width; x++) {
if(pix[x]) {
// black pixel
for( ; space_counter>0; space_counter--) add_one_char(' ');
add_one_char(0);
} else {
space_counter++;
}
}
add_one_char(0x0d);
pix += off_rowbytes;
}
SetGWorld(saved_port, saved_gdh);
/* draw big text */
SetPort(dp);
InvalRect(&big_text_area);
}
void add_one_char(char what_char)
{
long old_size;
Ptr tail_ptr;
old_size = GetHandleSize(big_text_hdl);
if(cur_char_is_kanji && (what_char != 0x0d)) {
SetHandleSize(big_text_hdl, old_size + 2);
tail_ptr = StripAddress(*big_text_hdl);
tail_ptr += old_size;
if(what_char == ' ') {
BlockMove((void*)&kanji_space, tail_ptr, 2);
} else {
BlockMove((void*)&cur_kanji_char, tail_ptr, 2);
}
} else {
SetHandleSize(big_text_hdl, old_size + 1);
tail_ptr = StripAddress(*big_text_hdl);
tail_ptr += old_size;
if(what_char == 0) {
*tail_ptr = cur_ascii_char;
} else {
*tail_ptr = what_char;
}
}
}
void put_big_text_into_scrap(void)
{
HLock(big_text_hdl);
ZeroScrap();
PutScrap(GetHandleSize(big_text_hdl), 'TEXT', *big_text_hdl);
HUnlock(big_text_hdl);
}