Ejemplo n.º 1
0
NetListItem::NetListItem(event_type type, const char* text, const BFont* font, uint32 level, bool expanded)
				:	BListItem(level, expanded)
{
	font_height height;
	font->GetHeight(&height);
	fFontAscent = height.ascent;
	fLineHeight = static_cast<int>(height.ascent + height.descent + height.leading);

	fText = static_cast<char*>(malloc(strlen(text) + 1));
	strcpy(fText, text);
		
	fLineInfo.count = 1;
	fLineInfo.lines = (line_info*)malloc(sizeof(line_info));
	
	fLineInfo.lines[0].numChars = 0;
	fLineInfo.lines[0].numWrapPoints = 0;
	fLineInfo.lines[0].byteNum = (int32*)malloc(sizeof(int32));
	fLineInfo.lines[0].byteNum[0] = 0;
		
	for(int32 byteNum = 0; fText[byteNum] != 0; byteNum++)
	{ 
		if(BEGINS_CHAR(fText[byteNum]))
		{
			fLineInfo.lines[fLineInfo.count - 1].numChars++;
			if(WrapChar(fText[byteNum]))
				fLineInfo.lines[fLineInfo.count - 1].numWrapPoints++;
			if(fText[byteNum] == '\n')
			{
				// Don't count '\n' as a character
				fLineInfo.lines[fLineInfo.count - 1].numChars--;
				
				fLineInfo.count++;
				fLineInfo.lines = (line_info*)realloc(fLineInfo.lines, fLineInfo.count * sizeof(line_info));
				fLineInfo.lines[fLineInfo.count - 1].numChars = 0;
				fLineInfo.lines[fLineInfo.count - 1].numWrapPoints = 0;
				fLineInfo.lines[fLineInfo.count - 1].byteNum = (int32*)malloc(sizeof(int32));
				fLineInfo.lines[fLineInfo.count - 1].byteNum[0] = byteNum + 1;
			}
		}
	}
	
	// First pass finished, now know how many characters in each line
	for(int lineNum = 0; lineNum < fLineInfo.count; lineNum++)
	{
		fLineInfo.lines[lineNum].cumulativeWidth = (float*)malloc(fLineInfo.lines[lineNum].numChars * sizeof(float));
		fLineInfo.lines[lineNum].byteNum = (int32*)realloc(fLineInfo.lines[lineNum].byteNum, fLineInfo.lines[lineNum].numChars * sizeof(int32));
		fLineInfo.lines[lineNum].wrapPoints = (int32*)malloc(fLineInfo.lines[lineNum].numWrapPoints * sizeof(int32));
	
		// Get escapements
		float* tmpEscapements = new float[fLineInfo.lines[lineNum].numChars];
		font->GetEscapements(&fText[fLineInfo.lines[lineNum].byteNum[0]], fLineInfo.lines[lineNum].numChars, tmpEscapements);
		
		// Loop over that line to fill in details
		int charNum = -1;
		int wrapNum = -1;
		float cumulWidth = 0;
		for(int byteNum = fLineInfo.lines[lineNum].byteNum[0]; fText[byteNum] != '\n' && fText[byteNum] != 0; byteNum++)
		{
			if(BEGINS_CHAR(fText[byteNum]))
			{
				charNum++;
				fLineInfo.lines[lineNum].byteNum[charNum] = byteNum;
				cumulWidth += tmpEscapements[charNum];
				fLineInfo.lines[lineNum].cumulativeWidth[charNum] = cumulWidth;
				if(WrapChar(fText[byteNum]))
				{
					wrapNum++;
					fLineInfo.lines[lineNum].wrapPoints[wrapNum] = charNum;
				}
			}
		}
	}	
	
	fType = type;
}
Ejemplo n.º 2
0
Archivo: layer.c Proyecto: amade/screen
void LWrapChar(Layer *l, struct mchar *c, int y, int top, int bot, bool ins)
{
	Canvas *cvlist, *cvlnext;
	Viewport *vp, *evp, **vpp;
	int yy, y2, yy2, top2, bot2;
	int bce;

	if (l->l_pause.d)
		/* XXX: 'y'? */
		LayPauseUpdateRegion(l, 0, l->l_width - 1, top, bot);

	bce = c->colorbg;
	if (y != bot) {
		/* simple case: no scrolling */

		/* cursor after wrapping */
		yy = y == l->l_height - 1 ? y : y + 1;

		for (Canvas *cv = l->l_cvlist; cv; cv = cv->c_lnext) {
			if (l->l_pause.d && cv->c_slorient)
				continue;
			y2 = 0;	/* gcc -Wall */
			display = cv->c_display;
			if (D_blocked)
				continue;
			/* find the viewport of the wrapped character */
			for (vp = cv->c_vplist; vp; vp = vp->v_next) {
				y2 = y + vp->v_yoff;
				yy2 = yy + vp->v_yoff;
				if (yy2 >= vp->v_ys && yy2 <= vp->v_ye && vp->v_xoff >= vp->v_xs
				    && vp->v_xoff <= vp->v_xe)
					break;
			}
			if (vp == NULL)
				continue;	/* nothing to do, character not visible */
			/* find the viewport of the character at the end of the line */
			for (evp = cv->c_vplist; evp; evp = evp->v_next)
				if (y2 >= evp->v_ys && y2 <= evp->v_ye
				    && evp->v_xoff + l->l_width - 1 >= evp->v_xs
				    && evp->v_xoff + l->l_width - 1 <= evp->v_xe)
					break;	/* gotcha! */
			if (evp == NULL || (ins && vp->v_xoff + l->l_width - 1 > vp->v_ye)) {
				/* no wrapping possible */
				cvlist = l->l_cvlist;
				cvlnext = cv->c_lnext;
				l->l_cvlist = cv;
				cv->c_lnext = NULL;
				if (ins)
					LInsChar(l, c, 0, yy, NULL);
				else
					LPutChar(l, c, 0, yy);
				l->l_cvlist = cvlist;
				cv->c_lnext = cvlnext;
			} else {
				WrapChar(RECODE_MCHAR(c), vp->v_xoff + l->l_width, y2, vp->v_xoff, -1,
					 vp->v_xoff + l->l_width - 1, -1, ins);
			}
		}
	} else {
		/* hard case: scroll up */

		for (Canvas *cv = l->l_cvlist; cv; cv = cv->c_lnext) {
			if (l->l_pause.d && cv->c_slorient)
				continue;
			display = cv->c_display;
			if (D_blocked)
				continue;
			/* search for wrap viewport */
			for (vpp = &cv->c_vplist; (vp = *vpp); vpp = &vp->v_next) {
				yy2 = bot + vp->v_yoff;
				if (yy2 >= vp->v_ys && yy2 <= vp->v_ye && vp->v_xoff >= vp->v_xs
				    && vp->v_xoff + l->l_width - 1 <= vp->v_xe)
					break;
			}

			if (vp) {
				/* great, can use Wrap on the vp */
				/* temporarily remove vp from cvlist */
				*vpp = vp->v_next;
			}
			if (cv->c_vplist) {
				/* scroll all viewports != vp */
				cvlist = l->l_cvlist;
				cvlnext = cv->c_lnext;
				l->l_cvlist = cv;
				cv->c_lnext = NULL;
				LScrollV(l, 1, top, bot, bce);
				if (!vp) {
					if (ins)
						LInsChar(l, c, 0, bot, NULL);
					else
						LPutChar(l, c, 0, bot);
				}
				l->l_cvlist = cvlist;
				cv->c_lnext = cvlnext;
			}
			if (vp) {
				/* add vp back to cvlist */
				*vpp = vp;
				top2 = top + vp->v_yoff;
				bot2 = bot + vp->v_yoff;
				if (top2 < vp->v_ys)
					top2 = vp->v_ys;
				WrapChar(RECODE_MCHAR(c), vp->v_xoff + l->l_width, bot2, vp->v_xoff, top2,
					 vp->v_xoff + l->l_width - 1, bot2, ins);
			}
		}
	}
}