Beispiel #1
0
	// ScanNextToken
	// . The main scanning function; here we branch out and
	//   scan whatever the next token should be.
	void Scanner::ScanNextToken()
	{
		if(m_endedStream)
			return;

		if(!m_startedStream)
			return StartStream();

		// get rid of whitespace, etc. (in between tokens it should be irrelevent)
		ScanToNextToken();

		// check the latest simple key
		VerifySimpleKey();

		// maybe need to end some blocks
		PopIndentTo(INPUT.column);

		// *****
		// And now branch based on the next few characters!
		// *****

		// end of stream
		if(INPUT.peek() == EOF)
			return EndStream();

		if(INPUT.column == 0 && INPUT.peek() == Keys::Directive)
			return ScanDirective();

		// document token
		if(INPUT.column == 0 && Exp::DocStart.Matches(INPUT))
			return ScanDocStart();

		if(INPUT.column == 0 && Exp::DocEnd.Matches(INPUT))
			return ScanDocEnd();

		// flow start/end/entry
		if(INPUT.peek() == Keys::FlowSeqStart || INPUT.peek() == Keys::FlowMapStart)
			return ScanFlowStart();

		if(INPUT.peek() == Keys::FlowSeqEnd || INPUT.peek() == Keys::FlowMapEnd)
			return ScanFlowEnd();
	
		if(INPUT.peek() == Keys::FlowEntry)
			return ScanFlowEntry();

		// block/map stuff
		if(Exp::BlockEntry.Matches(INPUT))
			return ScanBlockEntry();

		if((m_flowLevel == 0 ? Exp::Key : Exp::KeyInFlow).Matches(INPUT))
			return ScanKey();

		if((m_flowLevel == 0 ? Exp::Value : Exp::ValueInFlow).Matches(INPUT))
			return ScanValue();

		// alias/anchor
		if(INPUT.peek() == Keys::Alias || INPUT.peek() == Keys::Anchor)
			return ScanAnchorOrAlias();

		// tag
		if(INPUT.peek() == Keys::Tag)
			return ScanTag();

		// special scalars
		if(m_flowLevel == 0 && (INPUT.peek() == Keys::LiteralScalar || INPUT.peek() == Keys::FoldedScalar))
			return ScanBlockScalar();

		if(INPUT.peek() == '\'' || INPUT.peek() == '\"')
			return ScanQuotedScalar();

		// plain scalars
		if((m_flowLevel == 0 ? Exp::PlainScalar : Exp::PlainScalarInFlow).Matches(INPUT))
			return ScanPlainScalar();

		// don't know what it is!
		throw ParserException(INPUT.line, INPUT.column, ErrorMsg::UNKNOWN_TOKEN);
	}
Beispiel #2
0
void Scanner::ScanNextToken() {
  if (m_endedStream) {
    return;
  }

  if (!m_startedStream) {
    return StartStream();
  }

  // get rid of whitespace, etc. (in between tokens it should be irrelevent)
  ScanToNextToken();

  // maybe need to end some blocks
  PopIndentToHere();

  // *****
  // And now branch based on the next few characters!
  // *****

  // end of stream
  if (!INPUT) {
    return EndStream();
  }

  if (INPUT.column() == 0 && INPUT.peek() == Keys::Directive) {
    return ScanDirective();
  }

  // document token
  if (INPUT.column() == 0 && Exp::DocStart().Matches(INPUT)) {
    return ScanDocStart();
  }

  if (INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT)) {
    return ScanDocEnd();
  }

  // flow start/end/entry
  if (INPUT.peek() == Keys::FlowSeqStart ||
      INPUT.peek() == Keys::FlowMapStart) {
    return ScanFlowStart();
  }

  if (INPUT.peek() == Keys::FlowSeqEnd || INPUT.peek() == Keys::FlowMapEnd) {
    return ScanFlowEnd();
  }

  if (INPUT.peek() == Keys::FlowEntry) {
    return ScanFlowEntry();
  }

  // block/map stuff
  if (Exp::BlockEntry().Matches(INPUT)) {
    return ScanBlockEntry();
  }

  if ((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT)) {
    return ScanKey();
  }

  if (GetValueRegex().Matches(INPUT)) {
    return ScanValue();
  }

  // alias/anchor
  if (INPUT.peek() == Keys::Alias || INPUT.peek() == Keys::Anchor) {
    return ScanAnchorOrAlias();
  }

  // tag
  if (INPUT.peek() == Keys::Tag) {
    return ScanTag();
  }

  // special scalars
  if (InBlockContext() && (INPUT.peek() == Keys::LiteralScalar ||
                           INPUT.peek() == Keys::FoldedScalar)) {
    return ScanBlockScalar();
  }

  if (INPUT.peek() == '\'' || INPUT.peek() == '\"') {
    return ScanQuotedScalar();
  }

  // plain scalars
  if ((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow())
          .Matches(INPUT)) {
    return ScanPlainScalar();
  }

  // don't know what it is!
  throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN);
}
Beispiel #3
0
void CPDF::Close()
{
	Page *P;
	Font *F;

	// write Courier font
	Obj *CourierObj = NewObject();
	fprintf(PDFFile, "%d 0 obj\n<< /Type /Font /Subtype /Type1 /BaseFont /Courier >>\nendobj\n", CourierObj->id);

	// write single dot XObject
	Obj *Dot = NewObject();
	fprintf(PDFFile, "%d 0 obj\n<< /Type /XObject /Subtype /Form /FormType 1 /BBox [-0.5 -0.5 0.5 0.5] /Marix [1 0 0 1 0 0] /Resources << /ProcSet [/PDF] >> /Length 148 >>\nstream\n", Dot->id);
	fprintf(PDFFile, "0 0.5 m 0.27553 0.5 0.5 0.27553 0.5 0 c 0.5 -0.27553 0.27553 -0.5 0 -0.5 c -0.27553 -0.5 -0.5 -0.27553 -0.5 0 c -0.5 0.27553 -0.27553 0.5 0 0.5 c f\n");
	fprintf(PDFFile, "endstream\nendobj\n");

	// write custom fonts
	F = FontList;
	while(F)
	{
		int c;
		Obj *FontHead = NewObject();
		F->id = FontHead->id;
		F->Glyphs[32].Begin(F->State);

		// 6/72 = 0.083333333333
		fprintf(PDFFile, "%d 0 obj\n<< /Type /Font /Subtype /Type3 /FontBBox [0 0 %0.2f 10] /FontMatrix [0.083333333333 0 0 0.083333333333 0 0]", FontHead->id, (float)F->Glyphs[32].GetWidth() / (VIRTUAL_DPI / 72));
		fprintf(PDFFile, " /CharProcs %d 0 R /Encoding %d 0 R /FirstChar 0 /LastChar 255 /Widths [", FontHead->id+2, FontHead->id+1);
		for(c = 0; c < 256; c++)
		{
			fprintf(PDFFile, "%0.2f ", (float)F->Glyphs[c].GetWidth() / (VIRTUAL_DPI / 72));
		} 
		fprintf(PDFFile, "] /ToUnicode %d 0 R >>\nendobj\n", FontHead->id+3);

		/* encoding */
		Obj *T = NewObject();
		fprintf(PDFFile, "%d 0 obj\n<< /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [0 ", FontHead->id+1);
		for(c = 0; c < 256; c++)
		{
			fprintf(PDFFile, "/%s_%d ", F->Name, c);
		}
		fprintf(PDFFile, "] >>\nendobj\n");

		/* CharProcs */
		T = NewObject();
		fprintf(PDFFile, "%d 0 obj\n<< ", FontHead->id+2);
		for(c = 0; c < 256; c++)
		{
			fprintf(PDFFile, "/%s_%d %d 0 R ", F->Name, c, FontHead->id+4+c);
		}
		fprintf(PDFFile, ">>\nendobj\n");

		/* ToUnicode (always the same) */
		NewStream();
			AddText("/CIDInit /ProcSet findresource begin\n");
			AddText("12 dict begin\n");
			AddText("begincmap\n");
			AddText("/CIDSystemInfo\n");
			AddText("<< /Registry (Adobe)\n");
			AddText("/Ordering (UCS)\n");
			AddText("/Supplement 0\n");
			AddText(">> def\n");
			AddText("/CMapName /Adobe-Identity-UCS def\n");
			AddText("/CMapNameType 2 def\n");
			AddText("1 begincodespacerange\n");
			AddText("<00> <FF>\n");
			AddText("endcodespacerange\n");
			AddText("2 beginbfrange\n");

			for(int base = 0; base < 0x100; base += 0x80)
			{
				Uint16 First32Targets[32] =
				{
					0x00e0, 0x00e8, 0x00f9, 0x00f2,	// à, è, ù, ò
					0x00ec, 0x00ba, 0x00a3, 0x00a1,	// ì, º, £, ¡
					0x00bf, 0x00d1, 0x00f1, 0x00a4,	// ¿, Ñ, ñ, ¤
					0xfb05, 0x00c5, 0x00e5, 0x00e7,	// ſt, Å, å, ç	- ligature might be wrong
					0x00a7, 0x00df, 0x00c6, 0x00e6,	// §, ß, Æ, æ
					0x00d8, 0x00f8, 0x00a8, 0x00c4,	// Ø, ø, ¨, Ä
					0x00d6, 0x00dc, 0x00e4, 0x00f6,	// Ö, Ü, ä, ö
					0x00df, 0x00c9, 0x00e9, 0xffe5	// ü, É, é, ¥
				};
				char Buffer[32];

				/* table based mapping, for Latin supplement characters + the occasional oddity */
				sprintf(Buffer, "<%02x> <%02x> [ ", base, base+0x1f);
				AddText(Buffer);
				for(int c = 0; c < 32; c++)
				{
					sprintf(Buffer, "<%04x> ", First32Targets[c]);
					AddText(Buffer);
				}
				AddText("]\n");

				/* ASCII area */
				sprintf(Buffer, "<%02x> <%02x> <0020>\n", base+0x20, base+0x7e);
				AddText(Buffer);

				/* zero with a slash (should have a combining long solidus overlay, can't seem to make that work) */
				sprintf(Buffer, "<%02x> <%02x> <0030>\n", base+0x7f, base+0x7f);
				AddText(Buffer);
			}

			AddText("endbfrange\n");
			AddText("endcmap\n");
			AddText("CMapName currentdict /CMap defineresource pop\n");
			AddText("end\n");
			AddText("end\n");
		EndStream();

		/* actual glyphs */
		for(c = 0; c < 256; c++)
		{
			Uint32 *M;
			F->Glyphs[c].Begin();
			float x = 0;
			NewStream();

			char TBuf[128];
			sprintf(TBuf, "%0.2f 9 0 0 %0.2f 9 d1 ", (float)F->Glyphs[c].GetWidth() / (VIRTUAL_DPI / 72), (float)F->Glyphs[c].GetWidth() / (VIRTUAL_DPI / 72));
			AddText(TBuf);
			while(M = F->Glyphs[c].GetLine())
			{
				float y = 9;
				Uint32 RC = *M;
				while(RC&((GLYPHLINE_START << 1)-1))
				{
					if(RC&GLYPHLINE_START)
						AddPoint( x, y);
					y -= 0.5f;
					RC <<= 1;
				}
				x += (float)F->Glyphs[c].GetXAdvance() / (VIRTUAL_DPI / 72);
			}
			EndStream();
		}

		F = F->Next;
	}
	
/*
	while(mask&((GLYPHLINE_START << 1)-1))
	{
		if(mask&GLYPHLINE_START) PutDot(PosX, PosY);
		PosY += 5;
		mask <<= 1;
	}
*/

/*	Obj *FontObj = NewObject();
	fprintf(PDFFile, "%d 0 obj\n<< /Type /Font /Subtype /Type3 /FontBBox [0 0 750 750] /FontMatrix [0.001 0 0 0.001 0 0]", FontObj->id);
	fprintf(PDFFile, " /CharProcs %d 0 R /Encoding %d 0 R /FirstChar 97 /LastChar 98 /Widths [1000 1000] >>\nendobj\n", FontObj->id+2, FontObj->id+1);

	Obj *T = NewObject();
	fprintf(PDFFile, "%d 0 obj\n<< /Type /Encoding /Differences [97 /square /triangle] >>\nendobj\n", FontObj->id+1);

	T = NewObject();
	fprintf(PDFFile, "%d 0 obj\n<< /square %d 0 R /triangle %d 0 R >>\nendobj\n", FontObj->id+2, FontObj->id+3, FontObj->id+4);

	NewStream();
		AddText("1000 0 0 0 750 750 d1 0 0 750 750 re f ");
	EndStream();
	NewStream();
		AddText("1000 0 0 0 750 750 d1 0 0 m 375 750 l 750 0 l f ");
	EndStream();*/

//	fprintf(PDFFile, "%d 0 obj\n<< /square %d 0 R /triangle %d 0 R >>\nendobj\n", FontObj->id+2, FontObj->id+3, FontObj->id+4);

	// write actual pages
	P = PageList;
	int ObjectsIn = NumObjects;
	while(P)
	{
		P->FileOffset = ftell(PDFFile);
		P->id = NumObjects+1; NumObjects++;
		fprintf(PDFFile, "%d 0 obj\n\t", P->id);		// page entry (just points to the outlines)
		fputs("<< /Type /Page\n\t\t", PDFFile);
		fprintf(PDFFile, "/Parent %d 0 R\n\t\t", ObjectsIn+NumPages+1);
		fprintf(PDFFile, "/MediaBox [0 0 %d %d]\n\t\t", P->Width, P->Height);
		fputs("/Contents ", PDFFile);
		Obj *O = *(P->FirstObj);

		if(P->Next)
		{
			while(O != *P->Next->FirstObj)
			{
				fprintf(PDFFile, "%d 0 R ", O->id);
				O = O->Next;
			}
		}
		else
		{
			while(O != CourierObj)
			{
				fprintf(PDFFile, "%d 0 R ", O->id);
				O = O->Next;
			}
		}
		fputs(">>\nendobj\n", PDFFile);

		P = P->Next;
	}

	// write pages entry
	long PagesPos = ftell(PDFFile);
	fprintf(PDFFile, "%d 0 obj\n\t", NumObjects+1); NumObjects++;		// pages entry (there is one)
	fputs("<< /Type /Pages\n\t\t", PDFFile);
	fprintf(PDFFile, "/Resources << /XObject << /Dot %d 0 R >> /Font << /Courier %d 0 R ", Dot->id, CourierObj->id);
	F = FontList;
	while(F)
	{
		fprintf(PDFFile, "/%s %d 0 R ", F->Name, F->id);
		F = F->Next;
	}
	fprintf(PDFFile, " >> >>\n\t\t");
	fputs("/Kids [", PDFFile);
	P = PageList;
	while(P)
	{
		fprintf(PDFFile, "%d 0 R ", P->id);
		P = P->Next;
	}
	fputs("]\n\t\t", PDFFile);
	fprintf(PDFFile, "/Count %d\n\t", NumPages);
	fputs(">>\nendobj\n", PDFFile);

	// write catalogue
	long CataloguePos = ftell(PDFFile);
	fprintf(PDFFile, "%d 0 obj\n\t", NumObjects+1); NumObjects++;
	fprintf(PDFFile, "<< /Type /Catalog /Pages %d 0 R >>\nendobj\n", NumObjects-1);

	// write xref table
	long xrefpos = ftell(PDFFile);
	fprintf(PDFFile, "xref\n0 %d\n", NumObjects+1);
	fprintf(PDFFile, "0000000000 65535 f \n");
	Obj *O = ObjList;
	while(O)
	{
		fprintf(PDFFile, "%010d 00000 n \n", (int)O->FileOffset);
		O = O->Next;
	}
	P = PageList;
	while(P)
	{
		fprintf(PDFFile, "%010d 00000 n \n", (int)P->FileOffset);
		P = P->Next;
	}
	fprintf(PDFFile, "%010d 00000 n \n", (int)PagesPos);
	fprintf(PDFFile, "%010d 00000 n \n", (int)CataloguePos);

	fprintf(PDFFile, "trailer\n\t<</Size %d\n\t\t/Root %d 0 R\n\t>>\n", NumObjects+1, NumObjects);
	fprintf(PDFFile, "startxref\n%d\n", (int)xrefpos);
	fputs("%%EOF", PDFFile);

	fclose(PDFFile);

	// free memory
	while(PageList)
	{
		Page *N = PageList->Next;
		delete PageList;
		PageList = N;
	}
	while(ObjList)
	{
		Obj *N = ObjList->Next;
		delete ObjList;
		ObjList = N;
	}
	while(FontList)
	{
		Font *N = FontList->Next;
		delete FontList;
		FontList = N;
	}
}