/// <summary> /// Splits one word over several lines if it is to long to fit in one line. /// </summary> /// <param name="dots">The dot patterns of the word. /// (List of characters) List [ /// (List of raised pins in one Braille cell) List [dot pattern] /// ] /// </param> /// <param name="width">The width.</param> /// <returns> /// A list of lines for the split word. /// (List of lines) List [ /// (List of characters) List [ /// (List of raised pins in one Braille cell) List [dot pattern] /// ] /// ] /// </returns> private static List <List <List <int> > > splitWordOverLines(List <List <int> > dots, int width, ref RenderElement parentElement) { List <List <List <int> > > lines = new List <List <List <int> > >(); if (dots != null && width > BRAILLE_CHAR_WIDTH) { //Split the word char list in peaces width max length of 'width' int count = getMaxCountOfChars(width); if (count > 0) { string parVal = parentElement.GetValue() != null?parentElement.GetValue().ToString() : String.Empty; int i = 0; while (i < dots.Count) { int l = (i + count) < dots.Count ? count : (dots.Count - i); List <List <int> > subList = dots.GetRange(i, l); // create sub value string val = !String.IsNullOrEmpty(parVal) && parVal.Length > i? parVal.Substring(i, (parVal.Length > (i + l) ? l : parVal.Length - i) ) : String.Empty; // create sub element for each part RenderElement se = new RenderElement( parentElement.X, parentElement.Y + (lines.Count * (BRAILLE_CHAR_HEIGHT + INTER_LINE_HEIGHT)), getMinWidthOfString(subList), (BRAILLE_CHAR_HEIGHT + INTER_LINE_HEIGHT), val, parentElement ); parentElement.AddSubPart(se); se.Type = BrailleRendererPartType.WORD_PART; lines.Add(subList); i += count; } } } return(lines); }
/// <summary> /// Renders a paragraph. /// </summary> /// <param name="text">The text to render.</param> /// //TODO: make the rendering Positions available private List <List <List <int> > > renderParagraph(string text, int width, ref int maxUsedWidth, int yOffset = 0) { List <List <List <int> > > lines = new List <List <List <int> > >(); if (width > 0) { string[] words = GetWordsOfString(text); List <List <int> > currentLine = new List <List <int> >(); int availableWidth = width; int peX, peY, peW, peH = 0; peX = peY = peW = peH; peY = yOffset + lines.Count * (BRAILLE_CHAR_HEIGHT + INTER_LINE_HEIGHT); peX = width - availableWidth; RenderElement pe = new RenderElement(peX, peY, peW, peH, text); pe.Type = BrailleRendererPartType.PARAGRAPH; foreach (var word in words) { #region Rendering Element int eX, eY, eW, eH = 0; eX = eY = eW = eH; eY = yOffset + lines.Count * (BRAILLE_CHAR_HEIGHT + INTER_LINE_HEIGHT); eX = width - availableWidth; RenderElement e = new RenderElement(eX, eY, eW, eH, word); e.Type = BrailleRendererPartType.WORD; #endregion // get the dot patterns for that word List <List <int> > dots = getBrailleFromString(word); // check if the line has still some entries // if so, add a space char or open a new line if (currentLine.Count > 0) { // check if the line is full if (getMaxWidthOfString(currentLine) >= width) { makeNewLine(ref lines, ref currentLine, ref availableWidth, width, ref maxUsedWidth); } else { // add a space currentLine.Add(new List <int>()); availableWidth -= INTER_CHAR_WIDTH + BRAILLE_CHAR_WIDTH; } } //check if it fits into the available space if (!fitsWordInRestOfLine(dots, availableWidth)) //no { makeNewLine(ref lines, ref currentLine, ref availableWidth, width, ref maxUsedWidth); } e.X = width - availableWidth; e.Y = yOffset + lines.Count * (BRAILLE_CHAR_HEIGHT + INTER_LINE_HEIGHT); int minWidth = getMinWidthOfString(dots); if (minWidth > width) { //this will start a new line, so add a new line to the y position e.Y += BRAILLE_CHAR_HEIGHT + INTER_LINE_HEIGHT; //split the word into several lines List <List <List <int> > > wordLines = splitWordOverLines(dots, width, ref e); if (wordLines != null && wordLines.Count > 0) { //remove empty line if generated twice if (lines.Count > 0 && lines[lines.Count - 1].Count == 0) { lines.Remove(lines[Math.Max(0, lines.Count - 1)]); } // add them to the lines lines.AddRange(wordLines); //set the current line currentLine = lines[lines.Count - 1]; //remove from list so it will not added twice lines.Remove(currentLine); //update the available size availableWidth = width - getMinWidthOfString(currentLine); } } else { //fill the word into the line currentLine.AddRange(dots); e.Width = minWidth + INTER_CHAR_WIDTH; e.Height = BRAILLE_CHAR_HEIGHT + INTER_LINE_HEIGHT; //update the available width availableWidth -= getMinWidthOfString(dots) + INTER_CHAR_WIDTH; } #region Rendering Element pe.AddSubPart(e); #endregion } lines.Add(currentLine); // update the maxUsed Width maxUsedWidth = Math.Max(maxUsedWidth, (width - availableWidth)); elements.AddLast(pe); } return(lines); }