Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/accessible/base/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 21 kB image not shown  

Quelle  TextAttrs.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "TextAttrs.h"

#include "AccAttributes.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "StyleInfo.h"

#include "gfxTextRun.h"
#include "nsFontMetrics.h"
#include "nsLayoutUtils.h"
#include "nsContainerFrame.h"
#include "HyperTextAccessible.h"
#include "mozilla/AppUnits.h"

using namespace mozilla;
using namespace mozilla::a11y;

////////////////////////////////////////////////////////////////////////////////
// TextAttrsMgr
////////////////////////////////////////////////////////////////////////////////

void TextAttrsMgr::GetAttributes(AccAttributes* aAttributes) {
  MOZ_ASSERT(
      // 1. Hyper text accessible and attributes list must always be specified.
      mHyperTextAcc && aAttributes &&
          (
              // 2. If text attributes for a child of a container are being
              // requested, the offset accessible must be specified and it must
              // be text.
              (mOffsetAcc && mOffsetAcc->IsText()) ||
              // 3. If only default text attributes for a container are being
              // requested, the offset accessible must not be specified, but the
              // include default text attributes flag must be specified.
              (!mOffsetAcc && mIncludeDefAttrs)),
      "Wrong usage of TextAttrsMgr!");

  // Get the content and frame of the accessible. In the case of document
  // accessible it's role content and root frame.
  nsIContent* hyperTextElm = mHyperTextAcc->GetContent();
  if (!hyperTextElm) {
    return;  // XXX: we don't support text attrs on document with no body
  }

  nsIFrame* rootFrame = mHyperTextAcc->GetFrame();
  if (!rootFrame) {
    return;
  }

  nsIContent *offsetNode = nullptr, *offsetElm = nullptr;
  nsIFrame* frame = nullptr;
  if (mOffsetAcc) {
    offsetNode = mOffsetAcc->GetContent();
    offsetElm = nsCoreUtils::GetDOMElementFor(offsetNode);
    MOZ_ASSERT(offsetElm, "No element for offset accessible!");
    if (!offsetElm) return;

    frame = offsetElm->GetPrimaryFrame();
  }

  // "language" text attribute
  LangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);

  // "aria-invalid" text attribute
  InvalidTextAttr invalidTextAttr(hyperTextElm, offsetNode);

  // "background-color" text attribute
  BGColorTextAttr bgColorTextAttr(rootFrame, frame);

  // "color" text attribute
  ColorTextAttr colorTextAttr(rootFrame, frame);

  // "font-family" text attribute
  FontFamilyTextAttr fontFamilyTextAttr(rootFrame, frame);

  // "font-size" text attribute
  FontSizeTextAttr fontSizeTextAttr(rootFrame, frame);

  // "font-style" text attribute
  FontStyleTextAttr fontStyleTextAttr(rootFrame, frame);

  // "font-weight" text attribute
  FontWeightTextAttr fontWeightTextAttr(rootFrame, frame);

  // "auto-generated" text attribute
  AutoGeneratedTextAttr autoGenTextAttr(mHyperTextAcc, mOffsetAcc);

  // "text-underline(line-through)-style(color)" text attributes
  TextDecorTextAttr textDecorTextAttr(rootFrame, frame);

  // "text-position" text attribute
  TextPosTextAttr textPosTextAttr(rootFrame, frame, hyperTextElm, offsetNode);

  TextAttr* attrArray[] = {
      &langTextAttr,      &invalidTextAttr,    &bgColorTextAttr,
      &colorTextAttr,     &fontFamilyTextAttr, &fontSizeTextAttr,
      &fontStyleTextAttr, &fontWeightTextAttr, &autoGenTextAttr,
      &textDecorTextAttr, &textPosTextAttr};

  // Expose text attributes.
  for (TextAttr* attr : attrArray) {
    attr->Expose(aAttributes, mIncludeDefAttrs);
  }
}

////////////////////////////////////////////////////////////////////////////////
// LangTextAttr
////////////////////////////////////////////////////////////////////////////////

TextAttrsMgr::LangTextAttr::LangTextAttr(HyperTextAccessible* aRoot,
                                         nsIContent* aRootElm, nsIContent* aElm)
    : TTextAttr<nsString>(!aElm), mRootContent(aRootElm) {
  aRoot->Language(mRootNativeValue);
  mIsRootDefined = !mRootNativeValue.IsEmpty();

  if (aElm) {
    nsCoreUtils::GetLanguageFor(aElm, mRootContent, mNativeValue);
    mIsDefined = !mNativeValue.IsEmpty();
  }
}

TextAttrsMgr::LangTextAttr::~LangTextAttr() {}

void TextAttrsMgr::LangTextAttr::ExposeValue(AccAttributes* aAttributes,
                                             const nsString& aValue) {
  RefPtr<nsAtom> lang = NS_Atomize(aValue);
  aAttributes->SetAttribute(nsGkAtoms::language, lang);
}

////////////////////////////////////////////////////////////////////////////////
// InvalidTextAttr
////////////////////////////////////////////////////////////////////////////////

TextAttrsMgr::InvalidTextAttr::InvalidTextAttr(nsIContent* aRootElm,
                                               nsIContent* aElm)
    : TTextAttr<uint32_t>(!aElm), mRootElm(aRootElm) {
  mIsRootDefined = GetValue(mRootElm, &mRootNativeValue);
  if (aElm) mIsDefined = GetValue(aElm, &mNativeValue);
}

void TextAttrsMgr::InvalidTextAttr::ExposeValue(AccAttributes* aAttributes,
                                                const uint32_t& aValue) {
  switch (aValue) {
    case eFalse:
      aAttributes->SetAttribute(nsGkAtoms::invalid, nsGkAtoms::_false);
      break;

    case eGrammar:
      aAttributes->SetAttribute(nsGkAtoms::invalid, nsGkAtoms::grammar);
      break;

    case eSpelling:
      aAttributes->SetAttribute(nsGkAtoms::invalid, nsGkAtoms::spelling);
      break;

    case eTrue:
      aAttributes->SetAttribute(nsGkAtoms::invalid, nsGkAtoms::_true);
      break;
  }
}

bool TextAttrsMgr::InvalidTextAttr::GetValue(nsIContent* aElm,
                                             uint32_t* aValue) {
  nsIContent* elm = aElm;
  do {
    if (nsAccUtils::HasDefinedARIAToken(elm, nsGkAtoms::aria_invalid)) {
      static dom::Element::AttrValuesArray tokens[] = {
          nsGkAtoms::_false, nsGkAtoms::grammar, nsGkAtoms::spelling, nullptr};

      int32_t idx = nsAccUtils::FindARIAAttrValueIn(
          elm->AsElement(), nsGkAtoms::aria_invalid, tokens, eCaseMatters);
      switch (idx) {
        case 0:
          *aValue = eFalse;
          return true;
        case 1:
          *aValue = eGrammar;
          return true;
        case 2:
          *aValue = eSpelling;
          return true;
        default:
          *aValue = eTrue;
          return true;
      }
    }
  } while ((elm = elm->GetParent()) && elm != mRootElm);

  return false;
}

////////////////////////////////////////////////////////////////////////////////
// BGColorTextAttr
////////////////////////////////////////////////////////////////////////////////

TextAttrsMgr::BGColorTextAttr::BGColorTextAttr(nsIFrame* aRootFrame,
                                               nsIFrame* aFrame)
    : TTextAttr<nscolor>(!aFrame), mRootFrame(aRootFrame) {
  mIsRootDefined = GetColor(mRootFrame, &mRootNativeValue);
  if (aFrame) mIsDefined = GetColor(aFrame, &mNativeValue);
}

void TextAttrsMgr::BGColorTextAttr::ExposeValue(AccAttributes* aAttributes,
                                                const nscolor& aValue) {
  aAttributes->SetAttribute(nsGkAtoms::backgroundColor, Color{aValue});
}

bool TextAttrsMgr::BGColorTextAttr::GetColor(nsIFrame* aFrame,
                                             nscolor* aColor) {
  nscolor backgroundColor = aFrame->StyleBackground()->BackgroundColor(aFrame);
  if (NS_GET_A(backgroundColor) > 0) {
    *aColor = backgroundColor;
    return true;
  }

  nsContainerFrame* parentFrame = aFrame->GetParent();
  if (!parentFrame) {
    *aColor = aFrame->PresContext()->DefaultBackgroundColor();
    return true;
  }

  // Each frame of parents chain for the initially passed 'aFrame' has
  // transparent background color. So background color isn't changed from
  // 'mRootFrame' to initially passed 'aFrame'.
  if (parentFrame == mRootFrame) return false;

  return GetColor(parentFrame, aColor);
}

////////////////////////////////////////////////////////////////////////////////
// ColorTextAttr
////////////////////////////////////////////////////////////////////////////////

TextAttrsMgr::ColorTextAttr::ColorTextAttr(nsIFrame* aRootFrame,
                                           nsIFrame* aFrame)
    : TTextAttr<nscolor>(!aFrame) {
  mRootNativeValue = aRootFrame->StyleText()->mColor.ToColor();
  mIsRootDefined = true;

  if (aFrame) {
    mNativeValue = aFrame->StyleText()->mColor.ToColor();
    mIsDefined = true;
  }
}

void TextAttrsMgr::ColorTextAttr::ExposeValue(AccAttributes* aAttributes,
                                              const nscolor& aValue) {
  aAttributes->SetAttribute(nsGkAtoms::color, Color{aValue});
}

////////////////////////////////////////////////////////////////////////////////
// FontFamilyTextAttr
////////////////////////////////////////////////////////////////////////////////

TextAttrsMgr::FontFamilyTextAttr::FontFamilyTextAttr(nsIFrame* aRootFrame,
                                                     nsIFrame* aFrame)
    : TTextAttr<nsString>(!aFrame) {
  mIsRootDefined = GetFontFamily(aRootFrame, mRootNativeValue);

  if (aFrame) mIsDefined = GetFontFamily(aFrame, mNativeValue);
}

void TextAttrsMgr::FontFamilyTextAttr::ExposeValue(AccAttributes* aAttributes,
                                                   const nsString& aValue) {
  RefPtr<nsAtom> family = NS_Atomize(aValue);
  aAttributes->SetAttribute(nsGkAtoms::font_family, family);
}

bool TextAttrsMgr::FontFamilyTextAttr::GetFontFamily(nsIFrame* aFrame,
                                                     nsString& aFamily) {
  RefPtr<nsFontMetrics> fm =
      nsLayoutUtils::GetFontMetricsForFrame(aFrame, 1.0f);

  gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
  RefPtr<gfxFont> font = fontGroup->GetFirstValidFont();
  gfxFontEntry* fontEntry = font->GetFontEntry();
  aFamily.Append(NS_ConvertUTF8toUTF16(fontEntry->FamilyName()));
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// FontSizeTextAttr
////////////////////////////////////////////////////////////////////////////////

TextAttrsMgr::FontSizeTextAttr::FontSizeTextAttr(nsIFrame* aRootFrame,
                                                 nsIFrame* aFrame)
    : TTextAttr<nscoord>(!aFrame) {
  mDC = aRootFrame->PresContext()->DeviceContext();

  mRootNativeValue = aRootFrame->StyleFont()->mSize.ToAppUnits();
  mIsRootDefined = true;

  if (aFrame) {
    mNativeValue = aFrame->StyleFont()->mSize.ToAppUnits();
    mIsDefined = true;
  }
}

void TextAttrsMgr::FontSizeTextAttr::ExposeValue(AccAttributes* aAttributes,
                                                 const nscoord& aValue) {
  // Convert from nscoord to pt.
  //
  // Note: according to IA2, "The conversion doesn't have to be exact.
  // The intent is to give the user a feel for the size of the text."
  //
  // ATK does not specify a unit and will likely follow IA2 here.
  //
  // XXX todo: consider sharing this code with layout module? (bug 474621)
  float px = NSAppUnitsToFloatPixels(aValue, mozilla::AppUnitsPerCSSPixel());
  // Each pt is 4/3 of a CSS pixel.
  FontSize fontSize{NS_lround(px * 3 / 4)};

  aAttributes->SetAttribute(nsGkAtoms::font_size, fontSize);
}

////////////////////////////////////////////////////////////////////////////////
// FontStyleTextAttr
////////////////////////////////////////////////////////////////////////////////

TextAttrsMgr::FontStyleTextAttr::FontStyleTextAttr(nsIFrame* aRootFrame,
                                                   nsIFrame* aFrame)
    : TTextAttr<FontSlantStyle>(!aFrame) {
  mRootNativeValue = aRootFrame->StyleFont()->mFont.style;
  mIsRootDefined = true;

  if (aFrame) {
    mNativeValue = aFrame->StyleFont()->mFont.style;
    mIsDefined = true;
  }
}

void TextAttrsMgr::FontStyleTextAttr::ExposeValue(
    AccAttributes* aAttributes, const FontSlantStyle& aValue) {
  if (aValue.IsNormal()) {
    aAttributes->SetAttribute(nsGkAtoms::font_style, nsGkAtoms::normal);
  } else if (aValue.IsItalic()) {
    RefPtr<nsAtom> atom = NS_Atomize("italic");
    aAttributes->SetAttribute(nsGkAtoms::font_style, atom);
  } else {
    nsAutoCString s;
    aValue.ToString(s);
    nsString wide;
    CopyUTF8toUTF16(s, wide);
    aAttributes->SetAttribute(nsGkAtoms::font_style, std::move(wide));
  }
}

////////////////////////////////////////////////////////////////////////////////
// FontWeightTextAttr
////////////////////////////////////////////////////////////////////////////////

TextAttrsMgr::FontWeightTextAttr::FontWeightTextAttr(nsIFrame* aRootFrame,
                                                     nsIFrame* aFrame)
    : TTextAttr<FontWeight>(!aFrame) {
  mRootNativeValue = GetFontWeight(aRootFrame);
  mIsRootDefined = true;

  if (aFrame) {
    mNativeValue = GetFontWeight(aFrame);
    mIsDefined = true;
  }
}

void TextAttrsMgr::FontWeightTextAttr::ExposeValue(AccAttributes* aAttributes,
                                                   const FontWeight& aValue) {
  int value = aValue.ToIntRounded();
  aAttributes->SetAttribute(nsGkAtoms::fontWeight, value);
}

FontWeight TextAttrsMgr::FontWeightTextAttr::GetFontWeight(nsIFrame* aFrame) {
  // nsFont::width isn't suitable here because it's necessary to expose real
  // value of font weight (used font might not have some font weight values).
  RefPtr<nsFontMetrics> fm =
      nsLayoutUtils::GetFontMetricsForFrame(aFrame, 1.0f);

  gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
  RefPtr<gfxFont> font = fontGroup->GetFirstValidFont();

  // When there doesn't exist a bold font in the family and so the rendering of
  // a non-bold font face is changed so that the user sees what looks like a
  // bold font, i.e. synthetic bolding is used. (Simply returns false on any
  // platforms that don't use the multi-strike synthetic bolding.)
  if (font->ApplySyntheticBold()) {
    return FontWeight::BOLD;
  }

  // On Windows, font->GetStyle()->weight will give the same weight as
  // fontEntry->Weight(), the weight of the first font in the font group,
  // which may not be the weight of the font face used to render the
  // characters. On Mac, font->GetStyle()->weight will just give the same
  // number as getComputedStyle(). fontEntry->Weight() will give the weight
  // range supported by the font face used, so we clamp the weight that was
  // requested by style to what is actually supported by the font.
  gfxFontEntry* fontEntry = font->GetFontEntry();
  return fontEntry->Weight().Clamp(font->GetStyle()->weight);
}

////////////////////////////////////////////////////////////////////////////////
// AutoGeneratedTextAttr
////////////////////////////////////////////////////////////////////////////////
TextAttrsMgr::AutoGeneratedTextAttr::AutoGeneratedTextAttr(
    HyperTextAccessible* aHyperTextAcc, LocalAccessible* aAccessible)
    : TTextAttr<bool>(!aAccessible) {
  mRootNativeValue = false;
  mIsRootDefined = false;

  if (aAccessible) {
    mIsDefined = mNativeValue =
        ((aAccessible->NativeRole() == roles::STATICTEXT) ||
         (aAccessible->NativeRole() == roles::LISTITEM_MARKER));
  }
}

void TextAttrsMgr::AutoGeneratedTextAttr::ExposeValue(
    AccAttributes* aAttributes, const bool& aValue) {
  aAttributes->SetAttribute(nsGkAtoms::auto_generated, aValue);
}

////////////////////////////////////////////////////////////////////////////////
// TextDecorTextAttr
////////////////////////////////////////////////////////////////////////////////

TextAttrsMgr::TextDecorValue::TextDecorValue(nsIFrame* aFrame) {
  const nsStyleTextReset* textReset = aFrame->StyleTextReset();
  mStyle = textReset->mTextDecorationStyle;
  mColor = textReset->mTextDecorationColor.CalcColor(aFrame);
  mLine =
      textReset->mTextDecorationLine & (StyleTextDecorationLine::UNDERLINE |
                                        StyleTextDecorationLine::LINE_THROUGH);
}

TextAttrsMgr::TextDecorTextAttr::TextDecorTextAttr(nsIFrame* aRootFrame,
                                                   nsIFrame* aFrame)
    : TTextAttr<TextDecorValue>(!aFrame) {
  mRootNativeValue = TextDecorValue(aRootFrame);
  mIsRootDefined = mRootNativeValue.IsDefined();

  if (aFrame) {
    mNativeValue = TextDecorValue(aFrame);
    mIsDefined = mNativeValue.IsDefined();
  }
}

void TextAttrsMgr::TextDecorTextAttr::ExposeValue(
    AccAttributes* aAttributes, const TextDecorValue& aValue) {
  if (aValue.IsUnderline()) {
    RefPtr<nsAtom> underlineStyle =
        StyleInfo::TextDecorationStyleToAtom(aValue.Style());
    aAttributes->SetAttribute(nsGkAtoms::textUnderlineStyle, underlineStyle);

    aAttributes->SetAttribute(nsGkAtoms::textUnderlineColor,
                              Color{aValue.Color()});
    return;
  }

  if (aValue.IsLineThrough()) {
    RefPtr<nsAtom> lineThroughStyle =
        StyleInfo::TextDecorationStyleToAtom(aValue.Style());
    aAttributes->SetAttribute(nsGkAtoms::textLineThroughStyle,
                              lineThroughStyle);

    aAttributes->SetAttribute(nsGkAtoms::textLineThroughColor,
                              Color{aValue.Color()});
  }
}

////////////////////////////////////////////////////////////////////////////////
// TextPosTextAttr
////////////////////////////////////////////////////////////////////////////////

TextAttrsMgr::TextPosTextAttr::TextPosTextAttr(nsIFrame* aRootFrame,
                                               nsIFrame* aFrame,
                                               nsIContent* aRootElm,
                                               nsIContent* aElm)
    : TTextAttr<Maybe<TextPosValue>>(!aFrame && !aElm), mRootElm(aRootElm) {
  // Get the text-position values for the roots and children.
  // If we find an ARIA text-position value on a DOM element - searching up
  // from the supplied root DOM element - use the associated frame as the root
  // frame. This ensures that we're using the proper root frame for comparison.
  nsIFrame* ariaFrame = nullptr;
  Maybe<TextPosValue> rootAria = GetAriaTextPosValue(aRootElm, ariaFrame);
  if (rootAria && ariaFrame) {
    aRootFrame = ariaFrame;
  }
  Maybe<TextPosValue> rootLayout = GetLayoutTextPosValue(aRootFrame);
  Maybe<TextPosValue> childLayout;
  Maybe<TextPosValue> childAria;
  if (aFrame) {
    childLayout = GetLayoutTextPosValue(aFrame);
  }
  if (aElm) {
    childAria = GetAriaTextPosValue(aElm);
  }

  // Aria values take precedence over layout values.
  mIsRootDefined = rootAria || rootLayout;
  mRootNativeValue = rootAria ? rootAria : rootLayout;
  mIsDefined = childAria || childLayout;
  mNativeValue = childAria ? childAria : childLayout;

  // If there's no child text-position information from ARIA, and the child
  // layout info is equivalent to the root layout info (i.e., it's inherited),
  // then we should prefer the root information.
  if (!childAria && childLayout == rootLayout) {
    mIsDefined = false;
  }
}

void TextAttrsMgr::TextPosTextAttr::ExposeValue(
    AccAttributes* aAttributes, const Maybe<TextPosValue>& aValue) {
  if (aValue.isNothing()) {
    return;
  }

  RefPtr<nsAtom> atom = nullptr;
  switch (*aValue) {
    case eTextPosBaseline:
      atom = nsGkAtoms::baseline;
      break;

    case eTextPosSub:
      atom = nsGkAtoms::sub;
      break;

    case eTextPosSuper:
      atom = NS_Atomize("super");
      break;
  }

  if (atom) {
    aAttributes->SetAttribute(nsGkAtoms::textPosition, atom);
  }
}

Maybe<TextAttrsMgr::TextPosValue>
TextAttrsMgr::TextPosTextAttr::GetAriaTextPosValue(nsIContent* aElm) const {
  nsIFrame* ariaFrame = nullptr;
  return GetAriaTextPosValue(aElm, ariaFrame);
}

Maybe<TextAttrsMgr::TextPosValue>
TextAttrsMgr::TextPosTextAttr::GetAriaTextPosValue(nsIContent* aElm,
                                                   nsIFrame*& ariaFrame) const {
  // Search for the superscript and subscript roles that imply text-position.
  const nsIContent* elm = aElm;
  do {
    if (elm->IsElement()) {
      const mozilla::dom::Element* domElm = elm->AsElement();
      static const dom::Element::AttrValuesArray tokens[] = {
          nsGkAtoms::subscript, nsGkAtoms::superscript, nullptr};
      const int32_t valueIdx = domElm->FindAttrValueIn(
          kNameSpaceID_None, nsGkAtoms::role, tokens, eCaseMatters);
      ariaFrame = domElm->GetPrimaryFrame();
      if (valueIdx == 0) {
        return Some(eTextPosSub);
      }
      if (valueIdx == 1) {
        return Some(eTextPosSuper);
      }
    }
  } while ((elm = elm->GetParent()) && elm != mRootElm);

  ariaFrame = nullptr;
  return Nothing{};
}

Maybe<TextAttrsMgr::TextPosValue>
TextAttrsMgr::TextPosTextAttr::GetLayoutTextPosValue(nsIFrame* aFrame) const {
  const auto& verticalAlign = aFrame->StyleDisplay()->mVerticalAlign;
  if (verticalAlign.IsKeyword()) {
    switch (verticalAlign.AsKeyword()) {
      case StyleVerticalAlignKeyword::Baseline:
        return Some(eTextPosBaseline);
      case StyleVerticalAlignKeyword::Sub:
        return Some(eTextPosSub);
      case StyleVerticalAlignKeyword::Super:
        return Some(eTextPosSuper);
      // No good guess for the rest, so do not expose value of text-position
      // attribute.
      default:
        return Nothing{};
    }
  }

  const auto& length = verticalAlign.AsLength();
  if (length.ConvertsToPercentage()) {
    const float percentValue = length.ToPercentage();
    return percentValue > 0 ? Some(eTextPosSuper)
                            : (percentValue < 0 ? Some(eTextPosSub)
                                                : Some(eTextPosBaseline));
  }

  if (length.ConvertsToLength()) {
    const nscoord coordValue = length.ToLength();
    return coordValue > 0
               ? Some(eTextPosSuper)
               : (coordValue < 0 ? Some(eTextPosSub) : Some(eTextPosBaseline));
  }

  if (const nsIContent* content = aFrame->GetContent()) {
    if (content->IsHTMLElement(nsGkAtoms::sup)) return Some(eTextPosSuper);
    if (content->IsHTMLElement(nsGkAtoms::sub)) return Some(eTextPosSub);
  }

  return Nothing{};
}

98%


¤ Dauer der Verarbeitung: 0.9 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.