Dieser Artikel wurde maschinell übersetzt.

Neue Benutzeroberflächentechnologien

Prinzipien der Paginierung

Charles Petzold

Downloaden des Codebeispiels

Charles PetzoldEin paar Jahrzehnten haben Programmierer spezialisiert in der Computergrafik bekannt, dass die schwierigsten Aufgaben Bitmaps beinhalten oder, aber gute alte Text Vektorgrafiken nicht.

Text ist aus mehreren Gründen hart, von denen meisten beziehen sich auf die Tatsache, dass es in der Regel wünschenswert, dass der Text lesbar sein. Auch die tatsächliche Höhe der ein Stück Text ist nur beiläufig mit Bezug auf die Schriftart-Größe, und Zeichenbreiten variieren je nach dem Charakter. Zeichen werden oft in Wörter kombiniert (die zusammengehalten werden müssen). Wörter werden in Absätze, kombiniert, die in mehrere Zeilen getrennt werden müssen. Absätze werden in Dokumente, kombiniert die muss entweder ein Bildlauf durchgeführt oder werden in mehrere Seiten unterteilt.

In der letzten Ausgabe ich diskutierte die Druckunterstützung in Silverlight 4, und ich möchte nun Druck Text zu diskutieren. Der wichtigste Unterschied zwischen Text auf dem Bildschirm anzeigen und Drucken von Text auf dem Drucker lässt sich in eine einfache Wahrheit geeignet für Framing: die Druckerseite hat keine Bildlaufleisten.

Ein Programm, das muss mehr Text als passen auf einer Seite drucken muss den Text in mehrere Seiten getrennt werden. Dies ist eine nicht-triviale Programmieraufgabe bekannt als Paginierung. Ich finde es sehr interessant, dass Paginierung tatsächlich in den letzten Jahren an Bedeutung gewonnen hat selbst als Druck weniger wichtig geworden ist. Hier ist eine weitere einfache Wahrheit können Sie Rahmen und Aufmachungen auf Ihrer Wand: Paginierung — es ist nicht nur für Drucker nicht mehr.

Abholen alle e-Book-Reader- oder jedes kleines Gerät, das Sie können lesen Zeitschriften, Bücher oder sogar desktop Buch-Lese-Software — und finden Sie Dokumente, die in Seiten organisiert wurden. Manchmal werden diese Seiten vorformatiert und behoben (wie bei PDF und XPS-Dateiformat), aber in vielen Fällen Seiten können von dynamisch Umfließen (z. B. mit EPUB oder proprietäre e-Book-Formate). Dokumenten, die Umfließen werden können, kann etwas so einfach wie das Ändern des Schriftgrads verlangt einen ganzen Abschnitt des Dokuments dynamisch Formatierungstrennzeichen werden, während der Benutzer, wahrscheinlich ungeduldig wartet.

Paginieren on the Fly – und dabei schnell – eine, die außergewöhnlich schwierig sein kann einen nicht-trivialen programming Job verwandelt. Aber lassen Sie uns nicht erschrecken uns zu viel. Ich werde zu den harten Stuff im Laufe der Zeit aufbauen und jetzt wird beginnen sehr einfach.

Stapeln TextBlocks

Silverlight stellt mehrere Klassen, in denen Text angezeigt:

  • Das Glyphs-Element ist vielleicht der eine Klasse, mit der meisten Silverlight-Programmierer mindestens vertraut sind. Die Schriftart in Glyphs muss angegeben werden, entweder mit einer URL oder ein Stream-Objekt, die das Element am nützlichsten in fixierte Seite Dokumenten macht oder Dokument-Pakete, die stark auf bestimmte Schriftarten verlassen. Ich wird nicht diskutieren das Glyphs-Element.
  • Die Paragraph-Klasse ist neu in Silverlight 4 und imitiert eine prominente Klasse in der Document-Unterstützung von Windows Presentation Foundation (WPF). Aber Absatz wird meist in Verbindung mit RichTextBox verwendet, und es wird in Silverlight für Windows Phone 7 nicht unterstützt.
  • Und dann ist da noch TextBlock, die häufig auf einfache Weise verwendet wird, indem Sie die Text-Eigenschaft festlegen, aber es kann auch kombinieren Text verschiedener Formate Ihre Inlines-Eigenschaft. TextBlock hat auch die entscheidende Fähigkeit, Text in mehrere Zeilen umbrochen werden, wenn der Text die zulässige Breite überschreitet.

TextBlock hat das Verdienst, Silverlight-Programmierer vertraut und geeignet für unsere Bedürfnisse, so dass was ich verwenden werden.

Das SimplestPagination-Projekt (mit der herunterladbare Code für diesen Artikel verfügbar) soll nur-Text-Dokumente drucken. Das Programm behandelt jede Textzeile als eines Absatzes, das möglicherweise in mehrere Zeilen umbrochen werden muss. Das Programm nimmt jedoch implizit, dass dieser Absätze nicht sehr lang sind. Diese Annahme kommt aus der Begrenzung des Programms Absätze seitenübergreifend zu brechen. (Das ist der einfachste Teil des Namens SimplestPagination.) Wenn ein Absatzes auf eine Seite passen zu lang ist, wird der gesamte Absatz auf der nächsten Seite verschoben, und wenn der Absatz für eine einzelne Seite zu groß ist, dann wird es abgeschnitten.

Sie können das Programm SimplestPagination ausführen bit.ly/elqWgU. Es hat nur zwei Schaltflächen: Load- and -Print. Die Load-Taste zeigt ein OpenFileDialog-Steuerelements, mit dem Sie eine Datei aus dem lokalen Speicher auswählen kann. Print paginiert es und druckt es.

Die OpenFileDialog-Klasse gibt ein FileInfo-Objekt zurück. Die OpenText-Methode des FileInfo gibt einen StreamReader, die eine ReadLine-Methode für das Lesen ganze Textzeilen verfügt. Abbildung 1 wird der PrintPage-Ereignishandler.

Abbildung 1 PrintPage Ereignishandler des SimplestPagination

void OnPrintDocumentPrintPage(
  object sender, PrintPageEventArgs args) {

  Border border = new Border {
    Padding = new Thickness(
      Math.Max(0, desiredMargin.Left - args.PageMargins.Left),
      Math.Max(0, desiredMargin.Top - args.PageMargins.Top),
      Math.Max(0, desiredMargin.Right - args.PageMargins.Right),
      Math.Max(0, desiredMargin.Bottom - args.PageMargins.Bottom))
  };

  StackPanel stkpnl = new StackPanel();
  border.Child = stkpnl;
  string line = leftOverLine;

  while ((leftOverLine != null) || 
    ((line = streamReader.ReadLine()) != null)) {

    leftOverLine = null;

    // Check for blank lines; print them with a space
    if (line.Length == 0)
      line = " ";

    TextBlock txtblk = new TextBlock {
      Text = line,
      TextWrapping = TextWrapping.Wrap
    };

    stkpnl.Children.Add(txtblk);
    border.Measure(new Size(args.PrintableArea.Width, 
      Double.PositiveInfinity));

    // Check if the page is now too tall
    if (border.DesiredSize.Height > args.PrintableArea.Height &&
      stkpnl.Children.Count > 1) {

      // If so, remove the TextBlock and save the text for later
      stkpnl.Children.Remove(txtblk);
      leftOverLine = line;
      break;
    }
  }

  if (leftOverLine == null)
    leftOverLine = streamReader.ReadLine();

  args.PageVisual = border;
  args.HasMorePages = leftOverLine != null;
}

Wie üblich, ist die gedruckte Seite einer visuellen Struktur. Die Wurzel dieser bestimmten visuellen Struktur ist das Border-Element, das eine Padding-Eigenschaft um 48-Einheit (Hälfte-Zoll) Margen zu erhalten, wie angegeben im Feld DesiredMargins gegeben ist. Die PageMargins-Eigenschaft die Ereignisargumente bietet die Abmessungen der Unbedruckbare Ränder der Seite, so dass die Padding-Eigenschaft angeben zusätzlichen Speicherplatz, die Summe bis zu 48 bringen muss.

Eine StackPanel erfolgt dann ein Kind der Grenze und TextBlock-Elemente werden auf das StackPanel-Element hinzugefügt. Nach jeweils heißt die Measure-Methode der Grenze mit einer horizontalen Einschränkung der druckbare Breite der Seite und eine vertikale Einschränkung der Unendlichkeit. Die DesiredSize-Eigenschaft zeigt dann, wie groß die Grenze werden muss. Übersteigt die Höhe die Höhe des die PrintableArea dann das StackPanel-Element TextBlock entfernt werden muss (aber nicht wenn es der einzige).

Feld LeftOverLine speichert den Text, der nicht auf der Seite gedruckt werden. Ich benutze es auch, um zu signalisieren, dass das Dokument abgeschlossen, ist indem Sie ReadLine für die StreamReader ein letztes Mal aufrufen. (Natürlich hätten StreamReader eine PeekLine Methode, dieses Feld wäre nicht erforderlich.)

Der herunterladbare Code enthält einen Ordner mit einer Datei mit dem Namen EmmaFirstChapter.txt. Dies ist das erste Kapitel des Jane Austen's Roman, "Emma," speziell für dieses Programm vorbereitet: alle Absätze sind einzelne Zeilen, und sie Leerzeilen getrennt sind. Mit dem Silverlight-Font ist es etwa vier Seiten lang. Die gedruckten Seiten sind nicht leicht zu lesen, aber das ist nur, weil die Zeilen für den Schriftgrad zu breit sind.

Diese Datei zeigt auch ein kleines Problem mit dem Programm: es könnte sein, dass die Leerzeilen Absatz 1 auf einer Seite gehört. Wenn dies der Fall ist, sollte nicht es gedruckt werden. Aber das ist nur zusätzliche Logik.

Druck Textfelder mit tatsächlichen Absätze, könnten Sie Leerzeilen zwischen Absätzen, oder Sie es möglicherweise vorziehen, mehr Kontrolle durch Festlegen der Margin-Eigenschaft des TextBlock. Es ist auch möglich, dass einen Einzug der ersten Zeile durch Ändern der Anweisung, die die Text-Eigenschaft des TextBlock von diesem zuweist:

Text = line,
 
to this:
Text = "     " + line,

Aber keines dieser Techniken würde funktionieren gut, wenn Source-Code drucken.

Aufteilung den TextBlock

Nach dem Experimentieren mit dem SimplestPagination-Programm, werden Sie wahrscheinlich feststellen, dass seine größte Fehler die Unfähigkeit ist, den Absätzen seitenübergreifend zu brechen.

Ein Ansatz zum Beheben dieses Problems wird in das BetterPagination-Programm, das Sie an ausführen können veranschaulicht bit.ly/ekpdZb. Dieses Programm ist ähnlich wie SimplestPagination außer in Fällen wenn ein TextBlock das StackPanel-Steuerelement, hinzugefügt ist, die bewirkt, dass die Gesamthöhe die Seite übersteigt. SimplestPagination entfernt dieser Code einfach den gesamten TextBlock von StackPanel-Elements:

// Check if the page is now too tall
if (border.DesiredSize.Height > args.PrintableArea.Height &&
  stkpnl.Children.Count > 1) {

  // If so, remove the TextBlock and save the text for later
  stkpnl.Children.Remove(txtblk);
  leftOverLine = line;
  break;
}
BetterPagination now calls a method named RemoveText:
// Check if the page is now too tall
if (border.DesiredSize.Height > args.PrintableArea.Height) {
  // If so, remove some text and save it for later
  leftOverLine = RemoveText(border, txtblk, args.PrintableArea);
  break;
}

RemoveText zeigt Abbildung 2. Die Methode einfach entfernt ein Wort zu einem Zeitpunkt vom Ende der Text-Eigenschaft des TextBlock und überprüft, ob das hilft den TextBlock auf die Seite passen. Alle entfernte Text wird in einen StringBuilder akkumuliert, die PrintPage Ereignishandler als LeftOverLine für die nächste Seite speichert.

Abbildung 2 Die RemoveText-Methode BetterPagination

string RemoveText(Border border, 
  TextBlock txtblk, Size printableArea) {

  StringBuilder leftOverText = new StringBuilder();

  do {
    int index = txtblk.Text.LastIndexOf(' ');

    if (index == -1)
      index = 0;

    leftOverText.Insert(0, txtblk.Text.Substring(index));
    txtblk.Text = txtblk.Text.Substring(0, index);
    border.Measure(new Size(printableArea.Width, 
      Double.PositiveInfinity));

    if (index == 0)
      break;
  }
  while (border.DesiredSize.Height > printableArea.Height);

  return leftOverText.ToString().TrimStart(' ');
}

Es ist nicht schön, aber es funktioniert. Denken Sie daran, dass wenn Sie mit formatierten Text (verschiedene Schriftarten, Schriftgrößen, Fett und kursiv) zu tun haben, dann Sie nicht mit der Text-Eigenschaft des TextBlock, sondern mit der Inlines-Eigenschaft arbeiten werde, und erschwert, die den Prozess enorm.

Und ja, es gibt definitiv schneller Möglichkeiten, dies zu tun, obwohl sie sicherlich komplexer sind. Beispielsweise kann ein binärer Algorithmus implementiert werden: die Hälfte die Worte können entfernt werden, wenn es auf die Seite passt, was entfernt war Halbjahr wiederhergestellt werden kann und wenn, die auf der Seite passt, dann was wiederhergestellt war Halbjahr kann entfernt werden, und so weiter.

Allerdings, denken Sie daran, die dies Code für Druck ist. Der Engpass des Druckens ist der Drucker selbst, so dass während der Code ein paar Sekunden jedes TextBlock-Tests zu verbringen könnte, wahrscheinlich nicht es wird so stark bemerkbar.

Aber vielleicht beginnen Sie Fragen sich, genau wie viel aus dem Nähkästchen geht, wenn Sie Maßnahme für das Stammelement aufrufen. Sicherlich alle einzelnen TextBlock-Elemente werden immer Maßnahme fordert, und verwenden sie Silverlight-Interna, zu bestimmen, wie viel Speicherplatz, die Textzeichenfolge tatsächlich belegt mit der bestimmten Schriftart und Schriftgröße.

Sie könnten Fragen, ob Code wie diesen auch für die Paginierung ein Dokument für eine video-Anzeige auf einem langsamen Gerät erträglich wäre.

So lassen Sie uns versuchen es.

Paginierung auf Windows-Telefon 7

Mein Ziel (die in diesem Artikel abgeschlossen sein wird nicht) ist zu bauen einen e-Book-Reader für Windows Phone 7 geeignet für Lesung Adressbuchdateien nur-Text von Project Gutenberg heruntergeladen (gutenberg.org). Wie Sie wissen vielleicht, Project Gutenberg stammt von 1971 und war die erste digitale Bibliothek. Seit vielen Jahren, es sich auf die Public-Domain-Bücher – sehr oft die Klassiker der englischen Literatur – in einem nur-Text-ASCII-Format. Die vollständige "Emma" von Jane Austen ist beispielsweise die Datei gutenberg.org/files/158/158.txt.

Jedes Buch ist durch eine positive ganze Zahl für den Dateinamen identifiziert. Wie Sie hier sehen können, "Emma" ist 158 und seine Textversion ist in der Datei 158.txt. In den letzten Jahren hat Project Gutenberg andere Formate wie EPUB und HTML bereitgestellt, aber ich werde mit nur-Text für dieses Projekt aus offensichtlichen Gründen der Einfachheit-stick.

Das EmmaReader-Projekt für Windows Phone 7 enthält 158. Txt als Ressource und können Sie das gesamte Buch auf dem Handy lesen. Abbildung 3 zeigt das Programm auf dem Windows Phone 7-Emulator. Für Bewegungsunterstützung, das Projekt erfordert das Silverlight für Windows-Telefon Toolkit zum Herunterladen von silverlight.codeplex.com. Klaps oder Flick überlassen um zur nächsten Seite zu wechseln; schlagen Sie Recht auf der vorherigen Seite gehen.

EmmaReader Running on the Windows Phone 7 Emulator

Abbildung 3 EmmaReader, die auf den Windows 7-Telefon-Emulator

Das Programm hat fast keine Funktionen außer denen muss man es einigermaßen nutzbar machen. Offensichtlich ich werde werden Verbesserung dieses Programm, insbesondere damit Sie andere Bücher neben "Emma" lesen – vielleicht sogar Bücher Ihrer eigenen Wahl! Aber für Nageln Sie die Grundlagen, ist es einfacher, sich auf ein einzelnes Buch.

Wenn Sie 158.txt untersuchen, entdecken Sie das wichtigste Merkmal der nur-Text Project Gutenberg-Dateien: jeder Absatz besteht aus einem oder mehreren aufeinander folgenden 72 Zeichen Linien durch eine Leerzeile getrennt. Um dies in einem Format geeignet für TextBlock Umbruchoption für Zeilen umzuwandeln, wird einige Vorverarbeitung benötigt, um diese einzelnen aufeinander folgenden Zeilen in eine verketten. Dies ist in der PreprocessBook-Methode in EmmaReader durchgeführt. Das gesamte Buch — einschließlich leere Zeilen zwischen den Absätzen — wird dann als ein Feld mit dem Namen Absätze des Typs Liste <string> gespeichert. Diese Version des Programms versucht nicht, das Buch in Kapitel aufzuteilen.

Wie das Buch paginiert ist, wird jede Seite als ein Objekt vom Typ PageInfo mit nur zwei Ganzzahleigenschaften identifiziert: ParagraphIndex ist ein Index in der Liste den Absätzen und CharacterIndex ist ein Index in die Zeichenfolge für dieses Absatzes. Diese zwei Indizes zeigen die Absatz- und Zeichenformate, die die Seite beginnt. Die zwei Indizes für die erste Seite sind offensichtlich beide NULL. Da jede Seite paginiert wird, werden die Indizes für die nächste Seite bestimmt.

Das Programm versucht nicht, das gesamte Buch auf einmal paginieren. Mit dem Seitenlayout, die, das ich definiert haben, und die Standardschriftart Silverlight für Windows Phone 7, "Emma" wuchert aus zu 845 Seiten und neun Minuten, um es bei der Ausführung auf einem echten Gerät erfordert. Offensichtlich die Technik ich verwende für die Paginierung — erfordern Silverlight eine Maßübergabe für jede Seite, und sehr oft viele Male durchführen, wenn ein Absatz von einer Seite zur nächsten weiter — nimmt eine Abgabe. Ich werde einige schnelleren Techniken in späteren Spalten erforscht werden.

Aber das Programm braucht nicht das gesamte Buch auf einmal paginieren. Wie Sie Lesung am Anfang eines Buches starten und gehen Sie von Seite, muss das Programm nur auf einer Seite zu einem Zeitpunkt paginieren.

Funktionen und Anforderungen

Ich dachte ursprünglich, dass dieser ersten Version von EmmaReader keine Funktionen außer denen überhaupt notwendig, das Buch lesen von Anfang bis Ende. Aber das wäre grausam. Genommen Sie an, Sie sind das Buch zu lesen, Sie zu Seite 100 oder so bekommen haben und Sie schalten Sie den Bildschirm, um das Telefon in Ihrer Tasche einsetzen. Zu dieser Zeit ist das Programm veraltet gekennzeichnet, was bedeutet, dass Sie im wesentlichen beendet wird. Wenn Sie den Bildschirm wieder aktivieren, das Programm startet neu und Sie sind zurück zu Seite 1. Sie müssten dann tippen Sie auf 99 Seiten weiter lesen, wo Sie aufgehört!

Aus diesem Grund speichert das Programm die aktuelle Seitenzahl in isoliertem Speicher, wenn das Programm veraltet oder beendeten ist. Sie werden immer wieder auf die Seite springen, die Sie gelassen. (Wenn Sie mit dieser Funktion experimentieren bei der Programmausführung unter Visual Studio, entweder auf den Emulator oder eine tatsächliche Telefon, achten Sie darauf, das Programm zu beenden durch Drücken der Schaltfläche "zurück", nicht durch Anhalten Debuggen in Visual Studio. Debuggen beenden erlaubt nicht das Programm ordnungsgemäß beenden und isolierten Speicher zugreifen.)

Speichern die Seitenzahl in isoliertem Speicher nicht tatsächlich genug. Wenn nur die Seitenzahl gespeichert wurde, müsste das Programm dann die ersten 99 Seiten aufteilen, um die Hundertstel anzuzeigen. Das Programm benötigt mindestens das PageInfo-Objekt für diese Seite.

Aber dieses einzelne PageInfo-Objekt ist nicht genug, entweder. Angenommen, das Programm lädt erneut, es verwendet das PageInfo-Objekt anzuzeigende Seite 100, und dann Sie sich entscheiden, Ihren Finger flick Recht zur vorherigen Seite gehen. Das Programm nicht das PageInfo-Objekt für Seite 99, so muss es die ersten 98 Seiten Seiten neu nummerieren.

Aus diesem Grund wie Sie schrittweise das Buch und jede Seite paginiert wird lesen, führt das Programm eine Liste des Typs Liste <PageInfo> mit allen PageInfo Objekten hat, dass es bisher festgestellt. Diese gesamte Liste wird in isoliertem Speicher gespeichert. Wenn Sie mit der Programm-Quellcode experimentieren — beispielsweise ändern das Layout oder die Schriftgröße oder das gesamte Buch durch einen anderen ersetzen – denken Sie daran, dass jede Änderung, die Paginierung wirkt sich diese Liste von PageInfo Objekte ungültig macht. Sie sollten das Programm aus dem Telefon (oder den Emulator) Löschen von halten Ihren Finger auf den Programmnamen auf der Liste, und wählen Sie deinstallieren. Dies ist derzeit die einzige Möglichkeit, die gespeicherten Daten aus dem isolierten Speicher zu löschen.

Hier ist das Content Raster in MainPage.xaml:

<Grid x:Name="ContentPanel" 
  Grid.Row="1" Background="White">
  <toolkit:GestureService.GestureListener>
  <toolkit:GestureListener 
    Tap="OnGestureListenerTap"
    Flick="OnGestureListenerFlick" />
  </toolkit:GestureService.GestureListener>
            
  <Border Name="pageHost" Margin="12,6">
    <StackPanel Name="stackPanel" />
  </Border>
</Grid>

Während der Paginierung das Programm erhält die ActualWidth und ActualHeight-Eigenschaft des Border-Elements und verwendet, die in der gleichen Weise, dass die PrintableArea-Eigenschaft in den Drucken-Programmen verwendet wird. Die TextBlock-Elemente für jeden Absatz (und Leerzeilen zwischen den Absätzen) werden auf das StackPanel-Element hinzugefügt.

Die Paginate-Methode zeigt Abbildung 4. Wie Sie sehen können, ist es sehr ähnlich wie die Methoden in der Druck-Programme mit der Ausnahme, dass es eine Liste von String-Objekten basiert auf ParagraphIndex und CharacterIndex zugreift. Die Methode aktualisiert auch diese Werte für die nächste Seite.

Abbildung 4 die Paginate-Methode in EmmaReader

void Paginate(ref int paragraphIndex, ref int characterIndex) {
  stackPanel.Children.Clear();

  while (paragraphIndex < paragraphs.Count) {
    // Skip if a blank line is the first paragraph on a page
    if (stackPanel.Children.Count == 0 &&
      characterIndex == 0 &&
      paragraphs[paragraphIndex].Length == 0) {
        paragraphIndex++;
        continue;
    }

    TextBlock txtblk = new TextBlock {
      Text = 
        paragraphs[paragraphIndex].Substring(characterIndex),
      TextWrapping = TextWrapping.Wrap,
      Foreground = blackBrush
    };

    // Check for a blank line between paragraphs
    if (txtblk.Text.Length == 0)
      txtblk.Text = " ";

    stackPanel.Children.Add(txtblk);
    stackPanel.Measure(new Size(pageHost.ActualWidth, 
      Double.PositiveInfinity));

    // Check if the StackPanel fits in the available height
    if (stackPanel.DesiredSize.Height > pageHost.ActualHeight) {
      // Strip words off the end until it fits
      do {
        int index = txtblk.Text.LastIndexOf(' ');

        if (index == -1)
          index = 0;

        txtblk.Text = txtblk.Text.Substring(0, index);
        stackPanel.Measure(new Size(pageHost.ActualWidth, 
          Double.PositiveInfinity));

        if (index == 0)
          break;
      }
      while (stackPanel.DesiredSize.Height > pageHost.ActualHeight);

      characterIndex += txtblk.Text.Length;

      // Skip over the space
      if (txtblk.Text.Length > 0)
        characterIndex++;

      break;
    }
    paragraphIndex++;
    characterIndex = 0;
  }

  // Flag the page beyond the last
  if (paragraphIndex == paragraphs.Count)
    paragraphIndex = -1;
}

Wie Sie in sehen Abbildung 3, das Programm zeigt eine Seitenzahl.Aber beachten Sie, dass es eine Anzahl von Seiten, nicht angezeigt wird, da dies bestimmt werden kann, bis das gesamte Buch paginiert ist.Wenn Sie mit kommerziellen e-Book-Leser vertraut sind, sind Sie wahrscheinlich wissen, dass die Anzeige von Seitenzahlen und Anzahl der Seiten ein großes Problem ist.

Eine Funktion, die Benutzer in e-Book-Reader notwendig finden ist die Fähigkeit, Schriftart oder Schriftgrad ändern.Jedoch aus Sicht des Programms, das hat tödliche Folgen: alle die Paginierungsinformationen bisher angesammelt hat, die verworfen werden, und das Buch auf die aktuelle Seite, die nicht sogar dieselbe Seite es war ist vor Formatierungstrennzeichen werden muss.

Ein weiteres nettes Feature in e-Book-Leser ist die Möglichkeit zum Navigieren zu den Anfängen der Kapitel.Trennung ein Buch in Kapitel hilft wirklich das Programm Paginierung beschäftigen.Jedes Kapitel beginnt auf einer neuen Seite, so dass die Seiten in jedem Kapitel unabhängig von den anderen Kapiteln paginiert werden können.Zu Beginn eines neuen Kapitels springen ist trivial.(Wenn der Benutzer dann Recht auf der letzten Seite des vorherigen Kapitel schnippt, muss jedoch das gesamte vorherige Kapitel re-paginated sein!)

Sie werden wahrscheinlich auch zustimmen, dass dieses Programm eine bessere Seitenübergang.Die neue Seite ist nur pop einrastet unbefriedigend, weil es nicht angemessene Feedback geben, die die Seite hat tatsächlich verwandelt, oder, dass nur eine Seite anstelle von mehreren Seiten aktiviert hat.Das Programm braucht auf jeden Fall etwas Arbeit.Inzwischen, genießen Sie den Roman.

Charles Petzold ist ein langjähriger Redakteur zu MSDN Magazin*.*Seinem jüngsten Buch "Programming Windows Phone 7" (Microsoft Press, 2010), steht als kostenloser Download auf bit.ly/cpebookpdf.

Dank der folgenden technischen Experten für die Überprüfung dieses Artikels: Jesse Liberty